@code-pushup/cli 0.39.0 → 0.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +1112 -606
- package/package.json +5 -5
- package/src/lib/history/history-command.d.ts +3 -2
- package/src/lib/history/history.model.d.ts +1 -0
- package/src/lib/history/utils.d.ts +3 -0
package/index.js
CHANGED
|
@@ -6,9 +6,6 @@ import { hideBin } from "yargs/helpers";
|
|
|
6
6
|
// packages/cli/src/lib/autorun/autorun-command.ts
|
|
7
7
|
import chalk7 from "chalk";
|
|
8
8
|
|
|
9
|
-
// packages/models/src/lib/audit.ts
|
|
10
|
-
import { z as z2 } from "zod";
|
|
11
|
-
|
|
12
9
|
// packages/models/src/lib/implementation/schemas.ts
|
|
13
10
|
import { MATERIAL_ICONS } from "vscode-material-icons";
|
|
14
11
|
import { z } from "zod";
|
|
@@ -74,6 +71,7 @@ function missingRefsForCategoriesErrorMsg(categories, plugins) {
|
|
|
74
71
|
}
|
|
75
72
|
|
|
76
73
|
// packages/models/src/lib/implementation/schemas.ts
|
|
74
|
+
var primitiveValueSchema = z.union([z.string(), z.number()]);
|
|
77
75
|
function executionMetaSchema(options2 = {
|
|
78
76
|
descriptionDate: "Execution start date and time",
|
|
79
77
|
descriptionDuration: "Execution duration in ms"
|
|
@@ -165,6 +163,7 @@ function hasNonZeroWeightedRef(refs) {
|
|
|
165
163
|
}
|
|
166
164
|
|
|
167
165
|
// packages/models/src/lib/audit.ts
|
|
166
|
+
import { z as z2 } from "zod";
|
|
168
167
|
var auditSchema = z2.object({
|
|
169
168
|
slug: slugSchema.describe("ID (unique within plugin)")
|
|
170
169
|
}).merge(
|
|
@@ -194,7 +193,7 @@ function getDuplicateSlugsInAudits(audits) {
|
|
|
194
193
|
}
|
|
195
194
|
|
|
196
195
|
// packages/models/src/lib/audit-output.ts
|
|
197
|
-
import { z as
|
|
196
|
+
import { z as z5 } from "zod";
|
|
198
197
|
|
|
199
198
|
// packages/models/src/lib/issue.ts
|
|
200
199
|
import { z as z3 } from "zod";
|
|
@@ -225,16 +224,61 @@ var issueSchema = z3.object(
|
|
|
225
224
|
{ description: "Issue information" }
|
|
226
225
|
);
|
|
227
226
|
|
|
227
|
+
// packages/models/src/lib/table.ts
|
|
228
|
+
import { z as z4 } from "zod";
|
|
229
|
+
var tableAlignmentSchema = z4.enum(["left", "center", "right"], {
|
|
230
|
+
description: "Cell alignment"
|
|
231
|
+
});
|
|
232
|
+
var tableColumnObjectSchema = z4.object({
|
|
233
|
+
key: z4.string(),
|
|
234
|
+
label: z4.string().optional(),
|
|
235
|
+
align: tableAlignmentSchema.optional()
|
|
236
|
+
});
|
|
237
|
+
var tableRowObjectSchema = z4.record(primitiveValueSchema, {
|
|
238
|
+
description: "Object row"
|
|
239
|
+
});
|
|
240
|
+
var tableRowPrimitiveSchema = z4.array(primitiveValueSchema, {
|
|
241
|
+
description: "Primitive row"
|
|
242
|
+
});
|
|
243
|
+
var tableSharedSchema = z4.object({
|
|
244
|
+
title: z4.string().optional().describe("Display title for table")
|
|
245
|
+
});
|
|
246
|
+
var tablePrimitiveSchema = tableSharedSchema.merge(
|
|
247
|
+
z4.object(
|
|
248
|
+
{
|
|
249
|
+
columns: z4.array(tableAlignmentSchema).optional(),
|
|
250
|
+
rows: z4.array(tableRowPrimitiveSchema)
|
|
251
|
+
},
|
|
252
|
+
{ description: "Table with primitive rows and optional alignment columns" }
|
|
253
|
+
)
|
|
254
|
+
);
|
|
255
|
+
var tableObjectSchema = tableSharedSchema.merge(
|
|
256
|
+
z4.object(
|
|
257
|
+
{
|
|
258
|
+
columns: z4.union([
|
|
259
|
+
z4.array(tableAlignmentSchema),
|
|
260
|
+
z4.array(tableColumnObjectSchema)
|
|
261
|
+
]).optional(),
|
|
262
|
+
rows: z4.array(tableRowObjectSchema)
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
description: "Table with object rows and optional alignment or object columns"
|
|
266
|
+
}
|
|
267
|
+
)
|
|
268
|
+
);
|
|
269
|
+
var tableSchema = (description = "Table information") => z4.union([tablePrimitiveSchema, tableObjectSchema], { description });
|
|
270
|
+
|
|
228
271
|
// packages/models/src/lib/audit-output.ts
|
|
229
272
|
var auditValueSchema = nonnegativeIntSchema.describe("Raw numeric value");
|
|
230
|
-
var auditDisplayValueSchema =
|
|
231
|
-
var auditDetailsSchema =
|
|
273
|
+
var auditDisplayValueSchema = z5.string({ description: "Formatted value (e.g. '0.9 s', '2.1 MB')" }).optional();
|
|
274
|
+
var auditDetailsSchema = z5.object(
|
|
232
275
|
{
|
|
233
|
-
issues:
|
|
276
|
+
issues: z5.array(issueSchema, { description: "List of findings" }).optional(),
|
|
277
|
+
table: tableSchema("Table of related findings").optional()
|
|
234
278
|
},
|
|
235
279
|
{ description: "Detailed information" }
|
|
236
280
|
);
|
|
237
|
-
var auditOutputSchema =
|
|
281
|
+
var auditOutputSchema = z5.object(
|
|
238
282
|
{
|
|
239
283
|
slug: slugSchema.describe("Reference to audit"),
|
|
240
284
|
displayValue: auditDisplayValueSchema,
|
|
@@ -244,7 +288,7 @@ var auditOutputSchema = z4.object(
|
|
|
244
288
|
},
|
|
245
289
|
{ description: "Audit information" }
|
|
246
290
|
);
|
|
247
|
-
var auditOutputsSchema =
|
|
291
|
+
var auditOutputsSchema = z5.array(auditOutputSchema, {
|
|
248
292
|
description: "List of JSON formatted audit output emitted by the runner process of a plugin"
|
|
249
293
|
}).refine(
|
|
250
294
|
(audits) => !getDuplicateSlugsInAudits2(audits),
|
|
@@ -261,13 +305,13 @@ function getDuplicateSlugsInAudits2(audits) {
|
|
|
261
305
|
}
|
|
262
306
|
|
|
263
307
|
// packages/models/src/lib/category-config.ts
|
|
264
|
-
import { z as
|
|
308
|
+
import { z as z6 } from "zod";
|
|
265
309
|
var categoryRefSchema = weightedRefSchema(
|
|
266
310
|
"Weighted references to audits and/or groups for the category",
|
|
267
311
|
"Slug of an audit or group (depending on `type`)"
|
|
268
312
|
).merge(
|
|
269
|
-
|
|
270
|
-
type:
|
|
313
|
+
z6.object({
|
|
314
|
+
type: z6.enum(["audit", "group"], {
|
|
271
315
|
description: "Discriminant for reference kind, affects where `slug` is looked up"
|
|
272
316
|
}),
|
|
273
317
|
plugin: slugSchema.describe(
|
|
@@ -288,8 +332,8 @@ var categoryConfigSchema = scorableSchema(
|
|
|
288
332
|
description: "Meta info for category"
|
|
289
333
|
})
|
|
290
334
|
).merge(
|
|
291
|
-
|
|
292
|
-
isBinary:
|
|
335
|
+
z6.object({
|
|
336
|
+
isBinary: z6.boolean({
|
|
293
337
|
description: 'Is this a binary category (i.e. only a perfect score considered a "pass")?'
|
|
294
338
|
}).optional()
|
|
295
339
|
})
|
|
@@ -305,7 +349,7 @@ function getDuplicateRefsInCategoryMetrics(metrics) {
|
|
|
305
349
|
metrics.map(({ slug, type, plugin }) => `${type} :: ${plugin} / ${slug}`)
|
|
306
350
|
);
|
|
307
351
|
}
|
|
308
|
-
var categoriesSchema =
|
|
352
|
+
var categoriesSchema = z6.array(categoryConfigSchema, {
|
|
309
353
|
description: "Categorization of individual audits"
|
|
310
354
|
}).refine(
|
|
311
355
|
(categoryCfg) => !getDuplicateSlugCategories(categoryCfg),
|
|
@@ -324,18 +368,18 @@ function getDuplicateSlugCategories(categories) {
|
|
|
324
368
|
}
|
|
325
369
|
|
|
326
370
|
// packages/models/src/lib/commit.ts
|
|
327
|
-
import { z as
|
|
328
|
-
var commitSchema =
|
|
371
|
+
import { z as z7 } from "zod";
|
|
372
|
+
var commitSchema = z7.object(
|
|
329
373
|
{
|
|
330
|
-
hash:
|
|
374
|
+
hash: z7.string({ description: "Commit SHA (full)" }).regex(
|
|
331
375
|
/^[\da-f]{40}$/,
|
|
332
376
|
"Commit SHA should be a 40-character hexadecimal string"
|
|
333
377
|
),
|
|
334
|
-
message:
|
|
335
|
-
date:
|
|
378
|
+
message: z7.string({ description: "Commit message" }),
|
|
379
|
+
date: z7.coerce.date({
|
|
336
380
|
description: "Date and time when commit was authored"
|
|
337
381
|
}),
|
|
338
|
-
author:
|
|
382
|
+
author: z7.string({
|
|
339
383
|
description: "Commit author name"
|
|
340
384
|
}).trim()
|
|
341
385
|
},
|
|
@@ -343,22 +387,22 @@ var commitSchema = z6.object(
|
|
|
343
387
|
);
|
|
344
388
|
|
|
345
389
|
// packages/models/src/lib/core-config.ts
|
|
346
|
-
import { z as
|
|
390
|
+
import { z as z13 } from "zod";
|
|
347
391
|
|
|
348
392
|
// packages/models/src/lib/persist-config.ts
|
|
349
|
-
import { z as
|
|
350
|
-
var formatSchema =
|
|
351
|
-
var persistConfigSchema =
|
|
393
|
+
import { z as z8 } from "zod";
|
|
394
|
+
var formatSchema = z8.enum(["json", "md"]);
|
|
395
|
+
var persistConfigSchema = z8.object({
|
|
352
396
|
outputDir: filePathSchema.describe("Artifacts folder").optional(),
|
|
353
397
|
filename: fileNameSchema.describe("Artifacts file name (without extension)").optional(),
|
|
354
|
-
format:
|
|
398
|
+
format: z8.array(formatSchema).optional()
|
|
355
399
|
});
|
|
356
400
|
|
|
357
401
|
// packages/models/src/lib/plugin-config.ts
|
|
358
|
-
import { z as
|
|
402
|
+
import { z as z11 } from "zod";
|
|
359
403
|
|
|
360
404
|
// packages/models/src/lib/group.ts
|
|
361
|
-
import { z as
|
|
405
|
+
import { z as z9 } from "zod";
|
|
362
406
|
var groupRefSchema = weightedRefSchema(
|
|
363
407
|
"Weighted reference to a group",
|
|
364
408
|
"Reference slug to a group within this plugin (e.g. 'max-lines')"
|
|
@@ -375,7 +419,7 @@ var groupSchema = scorableSchema(
|
|
|
375
419
|
getDuplicateRefsInGroups,
|
|
376
420
|
duplicateRefsInGroupsErrorMsg
|
|
377
421
|
).merge(groupMetaSchema);
|
|
378
|
-
var groupsSchema =
|
|
422
|
+
var groupsSchema = z9.array(groupSchema, {
|
|
379
423
|
description: "List of groups"
|
|
380
424
|
}).optional().refine(
|
|
381
425
|
(groups2) => !getDuplicateSlugsInGroups(groups2),
|
|
@@ -403,14 +447,14 @@ function getDuplicateSlugsInGroups(groups2) {
|
|
|
403
447
|
}
|
|
404
448
|
|
|
405
449
|
// packages/models/src/lib/runner-config.ts
|
|
406
|
-
import { z as
|
|
407
|
-
var outputTransformSchema =
|
|
408
|
-
var runnerConfigSchema =
|
|
450
|
+
import { z as z10 } from "zod";
|
|
451
|
+
var outputTransformSchema = z10.function().args(z10.unknown()).returns(z10.union([auditOutputsSchema, z10.promise(auditOutputsSchema)]));
|
|
452
|
+
var runnerConfigSchema = z10.object(
|
|
409
453
|
{
|
|
410
|
-
command:
|
|
454
|
+
command: z10.string({
|
|
411
455
|
description: "Shell command to execute"
|
|
412
456
|
}),
|
|
413
|
-
args:
|
|
457
|
+
args: z10.array(z10.string({ description: "Command arguments" })).optional(),
|
|
414
458
|
outputFile: filePathSchema.describe("Output path"),
|
|
415
459
|
outputTransform: outputTransformSchema.optional()
|
|
416
460
|
},
|
|
@@ -418,8 +462,8 @@ var runnerConfigSchema = z9.object(
|
|
|
418
462
|
description: "How to execute runner"
|
|
419
463
|
}
|
|
420
464
|
);
|
|
421
|
-
var onProgressSchema =
|
|
422
|
-
var runnerFunctionSchema =
|
|
465
|
+
var onProgressSchema = z10.function().args(z10.unknown()).returns(z10.void());
|
|
466
|
+
var runnerFunctionSchema = z10.function().args(onProgressSchema.optional()).returns(z10.union([auditOutputsSchema, z10.promise(auditOutputsSchema)]));
|
|
423
467
|
|
|
424
468
|
// packages/models/src/lib/plugin-config.ts
|
|
425
469
|
var pluginMetaSchema = packageVersionSchema().merge(
|
|
@@ -430,13 +474,13 @@ var pluginMetaSchema = packageVersionSchema().merge(
|
|
|
430
474
|
description: "Plugin metadata"
|
|
431
475
|
})
|
|
432
476
|
).merge(
|
|
433
|
-
|
|
477
|
+
z11.object({
|
|
434
478
|
slug: slugSchema.describe("Unique plugin slug within core config"),
|
|
435
479
|
icon: materialIconSchema
|
|
436
480
|
})
|
|
437
481
|
);
|
|
438
|
-
var pluginDataSchema =
|
|
439
|
-
runner:
|
|
482
|
+
var pluginDataSchema = z11.object({
|
|
483
|
+
runner: z11.union([runnerConfigSchema, runnerFunctionSchema]),
|
|
440
484
|
audits: pluginAuditsSchema,
|
|
441
485
|
groups: groupsSchema
|
|
442
486
|
});
|
|
@@ -462,22 +506,22 @@ function getMissingRefsFromGroups(pluginCfg) {
|
|
|
462
506
|
}
|
|
463
507
|
|
|
464
508
|
// packages/models/src/lib/upload-config.ts
|
|
465
|
-
import { z as
|
|
466
|
-
var uploadConfigSchema =
|
|
509
|
+
import { z as z12 } from "zod";
|
|
510
|
+
var uploadConfigSchema = z12.object({
|
|
467
511
|
server: urlSchema.describe("URL of deployed portal API"),
|
|
468
|
-
apiKey:
|
|
512
|
+
apiKey: z12.string({
|
|
469
513
|
description: "API key with write access to portal (use `process.env` for security)"
|
|
470
514
|
}),
|
|
471
515
|
organization: slugSchema.describe(
|
|
472
516
|
"Organization slug from Code PushUp portal"
|
|
473
517
|
),
|
|
474
518
|
project: slugSchema.describe("Project slug from Code PushUp portal"),
|
|
475
|
-
timeout:
|
|
519
|
+
timeout: z12.number({ description: "Request timeout in minutes (default is 5)" }).positive().int().optional()
|
|
476
520
|
});
|
|
477
521
|
|
|
478
522
|
// packages/models/src/lib/core-config.ts
|
|
479
|
-
var unrefinedCoreConfigSchema =
|
|
480
|
-
plugins:
|
|
523
|
+
var unrefinedCoreConfigSchema = z13.object({
|
|
524
|
+
plugins: z13.array(pluginConfigSchema, {
|
|
481
525
|
description: "List of plugins to be used (official, community-provided, or custom)"
|
|
482
526
|
}).min(1),
|
|
483
527
|
/** portal configuration for persisting results */
|
|
@@ -509,7 +553,7 @@ var DEFAULT_PERSIST_FILENAME = "report";
|
|
|
509
553
|
var DEFAULT_PERSIST_FORMAT = ["json", "md"];
|
|
510
554
|
|
|
511
555
|
// packages/models/src/lib/report.ts
|
|
512
|
-
import { z as
|
|
556
|
+
import { z as z14 } from "zod";
|
|
513
557
|
var auditReportSchema = auditSchema.merge(auditOutputSchema);
|
|
514
558
|
var pluginReportSchema = pluginMetaSchema.merge(
|
|
515
559
|
executionMetaSchema({
|
|
@@ -517,9 +561,9 @@ var pluginReportSchema = pluginMetaSchema.merge(
|
|
|
517
561
|
descriptionDuration: "Duration of the plugin run in ms"
|
|
518
562
|
})
|
|
519
563
|
).merge(
|
|
520
|
-
|
|
521
|
-
audits:
|
|
522
|
-
groups:
|
|
564
|
+
z14.object({
|
|
565
|
+
audits: z14.array(auditReportSchema).min(1),
|
|
566
|
+
groups: z14.array(groupSchema).optional()
|
|
523
567
|
})
|
|
524
568
|
).refine(
|
|
525
569
|
(pluginReport) => !getMissingRefsFromGroups2(pluginReport.audits, pluginReport.groups ?? []),
|
|
@@ -553,10 +597,10 @@ var reportSchema = packageVersionSchema({
|
|
|
553
597
|
descriptionDuration: "Duration of the collect run in ms"
|
|
554
598
|
})
|
|
555
599
|
).merge(
|
|
556
|
-
|
|
600
|
+
z14.object(
|
|
557
601
|
{
|
|
558
|
-
categories:
|
|
559
|
-
plugins:
|
|
602
|
+
categories: z14.array(categoryConfigSchema),
|
|
603
|
+
plugins: z14.array(pluginReportSchema).min(1),
|
|
560
604
|
commit: commitSchema.describe("Git commit for which report was collected").nullable()
|
|
561
605
|
},
|
|
562
606
|
{ description: "Collect output data" }
|
|
@@ -572,40 +616,40 @@ var reportSchema = packageVersionSchema({
|
|
|
572
616
|
);
|
|
573
617
|
|
|
574
618
|
// packages/models/src/lib/reports-diff.ts
|
|
575
|
-
import { z as
|
|
619
|
+
import { z as z15 } from "zod";
|
|
576
620
|
function makeComparisonSchema(schema) {
|
|
577
621
|
const sharedDescription = schema.description || "Result";
|
|
578
|
-
return
|
|
622
|
+
return z15.object({
|
|
579
623
|
before: schema.describe(`${sharedDescription} (source commit)`),
|
|
580
624
|
after: schema.describe(`${sharedDescription} (target commit)`)
|
|
581
625
|
});
|
|
582
626
|
}
|
|
583
627
|
function makeArraysComparisonSchema(diffSchema, resultSchema, description) {
|
|
584
|
-
return
|
|
628
|
+
return z15.object(
|
|
585
629
|
{
|
|
586
|
-
changed:
|
|
587
|
-
unchanged:
|
|
588
|
-
added:
|
|
589
|
-
removed:
|
|
630
|
+
changed: z15.array(diffSchema),
|
|
631
|
+
unchanged: z15.array(resultSchema),
|
|
632
|
+
added: z15.array(resultSchema),
|
|
633
|
+
removed: z15.array(resultSchema)
|
|
590
634
|
},
|
|
591
635
|
{ description }
|
|
592
636
|
);
|
|
593
637
|
}
|
|
594
|
-
var scorableMetaSchema =
|
|
638
|
+
var scorableMetaSchema = z15.object({
|
|
595
639
|
slug: slugSchema,
|
|
596
640
|
title: titleSchema,
|
|
597
641
|
docsUrl: docsUrlSchema
|
|
598
642
|
});
|
|
599
643
|
var scorableWithPluginMetaSchema = scorableMetaSchema.merge(
|
|
600
|
-
|
|
644
|
+
z15.object({
|
|
601
645
|
plugin: pluginMetaSchema.pick({ slug: true, title: true, docsUrl: true }).describe("Plugin which defines it")
|
|
602
646
|
})
|
|
603
647
|
);
|
|
604
648
|
var scorableDiffSchema = scorableMetaSchema.merge(
|
|
605
|
-
|
|
649
|
+
z15.object({
|
|
606
650
|
scores: makeComparisonSchema(scoreSchema).merge(
|
|
607
|
-
|
|
608
|
-
diff:
|
|
651
|
+
z15.object({
|
|
652
|
+
diff: z15.number().min(-1).max(1).describe("Score change (`scores.after - scores.before`)")
|
|
609
653
|
})
|
|
610
654
|
).describe("Score comparison")
|
|
611
655
|
})
|
|
@@ -616,10 +660,10 @@ var scorableWithPluginDiffSchema = scorableDiffSchema.merge(
|
|
|
616
660
|
var categoryDiffSchema = scorableDiffSchema;
|
|
617
661
|
var groupDiffSchema = scorableWithPluginDiffSchema;
|
|
618
662
|
var auditDiffSchema = scorableWithPluginDiffSchema.merge(
|
|
619
|
-
|
|
663
|
+
z15.object({
|
|
620
664
|
values: makeComparisonSchema(auditValueSchema).merge(
|
|
621
|
-
|
|
622
|
-
diff:
|
|
665
|
+
z15.object({
|
|
666
|
+
diff: z15.number().int().describe("Value change (`values.after - values.before`)")
|
|
623
667
|
})
|
|
624
668
|
).describe("Audit `value` comparison"),
|
|
625
669
|
displayValues: makeComparisonSchema(auditDisplayValueSchema).describe(
|
|
@@ -628,15 +672,15 @@ var auditDiffSchema = scorableWithPluginDiffSchema.merge(
|
|
|
628
672
|
})
|
|
629
673
|
);
|
|
630
674
|
var categoryResultSchema = scorableMetaSchema.merge(
|
|
631
|
-
|
|
675
|
+
z15.object({ score: scoreSchema })
|
|
632
676
|
);
|
|
633
677
|
var groupResultSchema = scorableWithPluginMetaSchema.merge(
|
|
634
|
-
|
|
678
|
+
z15.object({ score: scoreSchema })
|
|
635
679
|
);
|
|
636
680
|
var auditResultSchema = scorableWithPluginMetaSchema.merge(
|
|
637
681
|
auditOutputSchema.pick({ score: true, value: true, displayValue: true })
|
|
638
682
|
);
|
|
639
|
-
var reportsDiffSchema =
|
|
683
|
+
var reportsDiffSchema = z15.object({
|
|
640
684
|
commits: makeComparisonSchema(commitSchema).nullable().describe("Commits identifying compared reports"),
|
|
641
685
|
categories: makeArraysComparisonSchema(
|
|
642
686
|
categoryDiffSchema,
|
|
@@ -665,6 +709,291 @@ var reportsDiffSchema = z14.object({
|
|
|
665
709
|
})
|
|
666
710
|
);
|
|
667
711
|
|
|
712
|
+
// packages/utils/src/lib/text-formats/constants.ts
|
|
713
|
+
var NEW_LINE = "\n";
|
|
714
|
+
var TAB = " ";
|
|
715
|
+
var SPACE = " ";
|
|
716
|
+
|
|
717
|
+
// packages/utils/src/lib/text-formats/html/details.ts
|
|
718
|
+
function details(title, content, cfg = { open: false }) {
|
|
719
|
+
return `<details${cfg.open ? " open" : ""}>${NEW_LINE}<summary>${title}</summary>${NEW_LINE}${// ⚠️ The blank line is needed to ensure Markdown in content is rendered correctly.
|
|
720
|
+
NEW_LINE}${content}${NEW_LINE}${// @TODO in the future we could consider adding it only if the content ends with a code block
|
|
721
|
+
// ⚠️ The blank line ensure Markdown in content is rendered correctly.
|
|
722
|
+
NEW_LINE}</details>${// ⚠️ The blank line is needed to ensure Markdown after details is rendered correctly.
|
|
723
|
+
NEW_LINE}`;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// packages/utils/src/lib/text-formats/html/font-style.ts
|
|
727
|
+
var boldElement = "b";
|
|
728
|
+
function bold(text) {
|
|
729
|
+
return `<${boldElement}>${text}</${boldElement}>`;
|
|
730
|
+
}
|
|
731
|
+
var italicElement = "i";
|
|
732
|
+
function italic(text) {
|
|
733
|
+
return `<${italicElement}>${text}</${italicElement}>`;
|
|
734
|
+
}
|
|
735
|
+
var codeElement = "code";
|
|
736
|
+
function code(text) {
|
|
737
|
+
return `<${codeElement}>${text}</${codeElement}>`;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
// packages/utils/src/lib/text-formats/html/link.ts
|
|
741
|
+
function link(href, text) {
|
|
742
|
+
return `<a href="${href}">${text || href}"</a>`;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
// packages/utils/src/lib/transform.ts
|
|
746
|
+
function toArray(val) {
|
|
747
|
+
return Array.isArray(val) ? val : [val];
|
|
748
|
+
}
|
|
749
|
+
function objectToEntries(obj) {
|
|
750
|
+
return Object.entries(obj);
|
|
751
|
+
}
|
|
752
|
+
function deepClone(obj) {
|
|
753
|
+
return obj == null || typeof obj !== "object" ? obj : structuredClone(obj);
|
|
754
|
+
}
|
|
755
|
+
function toUnixPath(path) {
|
|
756
|
+
return path.replace(/\\/g, "/");
|
|
757
|
+
}
|
|
758
|
+
function capitalize(text) {
|
|
759
|
+
return `${text.charAt(0).toLocaleUpperCase()}${text.slice(
|
|
760
|
+
1
|
|
761
|
+
)}`;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
// packages/utils/src/lib/table.ts
|
|
765
|
+
function rowToStringArray({ rows, columns = [] }) {
|
|
766
|
+
if (Array.isArray(rows.at(0)) && typeof columns.at(0) === "object") {
|
|
767
|
+
throw new TypeError(
|
|
768
|
+
"Column can`t be object when rows are primitive values"
|
|
769
|
+
);
|
|
770
|
+
}
|
|
771
|
+
return rows.map((row) => {
|
|
772
|
+
if (Array.isArray(row)) {
|
|
773
|
+
return row.map(String);
|
|
774
|
+
}
|
|
775
|
+
const objectRow = row;
|
|
776
|
+
if (columns.length === 0 || typeof columns.at(0) === "string") {
|
|
777
|
+
return Object.values(objectRow).map(String);
|
|
778
|
+
}
|
|
779
|
+
return columns.map(
|
|
780
|
+
({ key }) => String(objectRow[key])
|
|
781
|
+
);
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
function columnsToStringArray({ rows, columns = [] }) {
|
|
785
|
+
const firstRow = rows.at(0);
|
|
786
|
+
const primitiveRows = Array.isArray(firstRow);
|
|
787
|
+
if (typeof columns.at(0) === "string" && !primitiveRows) {
|
|
788
|
+
throw new Error("invalid union type. Caught by model parsing.");
|
|
789
|
+
}
|
|
790
|
+
if (columns.length === 0) {
|
|
791
|
+
if (Array.isArray(firstRow)) {
|
|
792
|
+
return firstRow.map((_, idx) => String(idx));
|
|
793
|
+
}
|
|
794
|
+
return Object.keys(firstRow);
|
|
795
|
+
}
|
|
796
|
+
if (typeof columns.at(0) === "string") {
|
|
797
|
+
return columns.map(String);
|
|
798
|
+
}
|
|
799
|
+
const cols = columns;
|
|
800
|
+
return cols.map(({ label, key }) => label ?? capitalize(key));
|
|
801
|
+
}
|
|
802
|
+
function getColumnAlignmentForKeyAndIndex(targetKey, targetIdx, columns = []) {
|
|
803
|
+
const column = columns.at(targetIdx) ?? columns.find((col) => col.key === targetKey);
|
|
804
|
+
if (typeof column === "string") {
|
|
805
|
+
return column;
|
|
806
|
+
} else if (typeof column === "object") {
|
|
807
|
+
return column.align ?? "center";
|
|
808
|
+
} else {
|
|
809
|
+
return "center";
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
function getColumnAlignmentForIndex(targetIdx, columns = []) {
|
|
813
|
+
const column = columns.at(targetIdx);
|
|
814
|
+
if (column == null) {
|
|
815
|
+
return "center";
|
|
816
|
+
} else if (typeof column === "string") {
|
|
817
|
+
return column;
|
|
818
|
+
} else if (typeof column === "object") {
|
|
819
|
+
return column.align ?? "center";
|
|
820
|
+
} else {
|
|
821
|
+
return "center";
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
function getColumnAlignments({
|
|
825
|
+
rows,
|
|
826
|
+
columns = []
|
|
827
|
+
}) {
|
|
828
|
+
if (rows.at(0) == null) {
|
|
829
|
+
throw new Error("first row can`t be undefined.");
|
|
830
|
+
}
|
|
831
|
+
if (Array.isArray(rows.at(0))) {
|
|
832
|
+
const firstPrimitiveRow = rows.at(0);
|
|
833
|
+
return Array.from({ length: firstPrimitiveRow.length }).map(
|
|
834
|
+
(_, idx) => getColumnAlignmentForIndex(idx, columns)
|
|
835
|
+
);
|
|
836
|
+
}
|
|
837
|
+
const firstObject = rows.at(0);
|
|
838
|
+
return Object.keys(firstObject).map(
|
|
839
|
+
(key, idx) => getColumnAlignmentForKeyAndIndex(key, idx, columns)
|
|
840
|
+
);
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
// packages/utils/src/lib/text-formats/html/table.ts
|
|
844
|
+
function wrap(elem, content) {
|
|
845
|
+
return `<${elem}>${content}</${elem}>${NEW_LINE}`;
|
|
846
|
+
}
|
|
847
|
+
function wrapRow(content) {
|
|
848
|
+
const elem = "tr";
|
|
849
|
+
return `<${elem}>${NEW_LINE}${content}</${elem}>${NEW_LINE}`;
|
|
850
|
+
}
|
|
851
|
+
function table(tableData) {
|
|
852
|
+
if (tableData.rows.length === 0) {
|
|
853
|
+
throw new Error("Data can't be empty");
|
|
854
|
+
}
|
|
855
|
+
const tableHeaderCols = columnsToStringArray(tableData).map((s) => wrap("th", s)).join("");
|
|
856
|
+
const tableHeaderRow = wrapRow(tableHeaderCols);
|
|
857
|
+
const tableBody = rowToStringArray(tableData).map((arr) => {
|
|
858
|
+
const columns = arr.map((s) => wrap("td", s)).join("");
|
|
859
|
+
return wrapRow(columns);
|
|
860
|
+
}).join("");
|
|
861
|
+
return wrap("table", `${NEW_LINE}${tableHeaderRow}${tableBody}`);
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
// packages/utils/src/lib/text-formats/md/font-style.ts
|
|
865
|
+
var boldWrap = "**";
|
|
866
|
+
function bold2(text) {
|
|
867
|
+
return `${boldWrap}${text}${boldWrap}`;
|
|
868
|
+
}
|
|
869
|
+
var italicWrap = "_";
|
|
870
|
+
function italic2(text) {
|
|
871
|
+
return `${italicWrap}${text}${italicWrap}`;
|
|
872
|
+
}
|
|
873
|
+
var strikeThroughWrap = "~";
|
|
874
|
+
function strikeThrough(text) {
|
|
875
|
+
return `${strikeThroughWrap}${text}${strikeThroughWrap}`;
|
|
876
|
+
}
|
|
877
|
+
var codeWrap = "`";
|
|
878
|
+
function code2(text) {
|
|
879
|
+
return `${codeWrap}${text}${codeWrap}`;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
// packages/utils/src/lib/text-formats/md/headline.ts
|
|
883
|
+
function headline(text, hierarchy = 1) {
|
|
884
|
+
return `${"#".repeat(hierarchy)} ${text}${NEW_LINE}`;
|
|
885
|
+
}
|
|
886
|
+
function h(text, hierarchy = 1) {
|
|
887
|
+
return headline(text, hierarchy);
|
|
888
|
+
}
|
|
889
|
+
function h1(text) {
|
|
890
|
+
return headline(text, 1);
|
|
891
|
+
}
|
|
892
|
+
function h2(text) {
|
|
893
|
+
return headline(text, 2);
|
|
894
|
+
}
|
|
895
|
+
function h3(text) {
|
|
896
|
+
return headline(text, 3);
|
|
897
|
+
}
|
|
898
|
+
function h4(text) {
|
|
899
|
+
return headline(text, 4);
|
|
900
|
+
}
|
|
901
|
+
function h5(text) {
|
|
902
|
+
return headline(text, 5);
|
|
903
|
+
}
|
|
904
|
+
function h6(text) {
|
|
905
|
+
return headline(text, 6);
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
// packages/utils/src/lib/text-formats/md/image.ts
|
|
909
|
+
function image(src, alt) {
|
|
910
|
+
return ``;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
// packages/utils/src/lib/text-formats/md/link.ts
|
|
914
|
+
function link2(href, text) {
|
|
915
|
+
return `[${text || href}](${href})`;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
// packages/utils/src/lib/text-formats/md/list.ts
|
|
919
|
+
function li(text, order = "unordered") {
|
|
920
|
+
const style = order === "unordered" ? "-" : "- [ ]";
|
|
921
|
+
return `${style} ${text}`;
|
|
922
|
+
}
|
|
923
|
+
function indentation(text, level = 1) {
|
|
924
|
+
return `${TAB.repeat(level)}${text}`;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
// packages/utils/src/lib/text-formats/md/paragraphs.ts
|
|
928
|
+
function paragraphs(...sections) {
|
|
929
|
+
return sections.filter(Boolean).join(`${NEW_LINE}${NEW_LINE}`);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
// packages/utils/src/lib/text-formats/md/section.ts
|
|
933
|
+
function section(...contents) {
|
|
934
|
+
return `${lines(...contents)}${NEW_LINE}`;
|
|
935
|
+
}
|
|
936
|
+
function lines(...contents) {
|
|
937
|
+
return `${contents.filter(Boolean).join(NEW_LINE)}`;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
// packages/utils/src/lib/text-formats/md/table.ts
|
|
941
|
+
var alignString = /* @__PURE__ */ new Map([
|
|
942
|
+
["left", ":--"],
|
|
943
|
+
["center", ":--:"],
|
|
944
|
+
["right", "--:"]
|
|
945
|
+
]);
|
|
946
|
+
function tableRow(rows) {
|
|
947
|
+
return `|${rows.join("|")}|`;
|
|
948
|
+
}
|
|
949
|
+
function table2(data) {
|
|
950
|
+
if (data.rows.length === 0) {
|
|
951
|
+
throw new Error("Data can't be empty");
|
|
952
|
+
}
|
|
953
|
+
const alignmentRow = getColumnAlignments(data).map(
|
|
954
|
+
(s) => alignString.get(s) ?? String(alignString.get("center"))
|
|
955
|
+
);
|
|
956
|
+
return section(
|
|
957
|
+
`${lines(
|
|
958
|
+
tableRow(columnsToStringArray(data)),
|
|
959
|
+
tableRow(alignmentRow),
|
|
960
|
+
...rowToStringArray(data).map(tableRow)
|
|
961
|
+
)}`
|
|
962
|
+
);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
// packages/utils/src/lib/text-formats/index.ts
|
|
966
|
+
var md = {
|
|
967
|
+
bold: bold2,
|
|
968
|
+
italic: italic2,
|
|
969
|
+
strikeThrough,
|
|
970
|
+
code: code2,
|
|
971
|
+
link: link2,
|
|
972
|
+
image,
|
|
973
|
+
headline,
|
|
974
|
+
h,
|
|
975
|
+
h1,
|
|
976
|
+
h2,
|
|
977
|
+
h3,
|
|
978
|
+
h4,
|
|
979
|
+
h5,
|
|
980
|
+
h6,
|
|
981
|
+
indentation,
|
|
982
|
+
lines,
|
|
983
|
+
li,
|
|
984
|
+
section,
|
|
985
|
+
paragraphs,
|
|
986
|
+
table: table2
|
|
987
|
+
};
|
|
988
|
+
var html = {
|
|
989
|
+
bold,
|
|
990
|
+
italic,
|
|
991
|
+
code,
|
|
992
|
+
link,
|
|
993
|
+
details,
|
|
994
|
+
table
|
|
995
|
+
};
|
|
996
|
+
|
|
668
997
|
// packages/utils/src/lib/diff.ts
|
|
669
998
|
function matchArrayItemsByKey({
|
|
670
999
|
before,
|
|
@@ -782,40 +1111,48 @@ import chalk from "chalk";
|
|
|
782
1111
|
|
|
783
1112
|
// packages/utils/src/lib/reports/constants.ts
|
|
784
1113
|
var TERMINAL_WIDTH = 80;
|
|
785
|
-
var NEW_LINE = "\n";
|
|
786
1114
|
var SCORE_COLOR_RANGE = {
|
|
787
1115
|
GREEN_MIN: 0.9,
|
|
788
1116
|
YELLOW_MIN: 0.5
|
|
789
1117
|
};
|
|
1118
|
+
var CATEGORIES_TITLE = "\u{1F3F7} Categories";
|
|
790
1119
|
var FOOTER_PREFIX = "Made with \u2764 by";
|
|
791
1120
|
var CODE_PUSHUP_DOMAIN = "code-pushup.dev";
|
|
792
|
-
var README_LINK = "https://github.com/
|
|
1121
|
+
var README_LINK = "https://github.com/code-pushup/cli#readme";
|
|
793
1122
|
var reportHeadlineText = "Code PushUp Report";
|
|
794
1123
|
var reportOverviewTableHeaders = [
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
1124
|
+
{
|
|
1125
|
+
key: "category",
|
|
1126
|
+
label: "\u{1F3F7} Category",
|
|
1127
|
+
align: "left"
|
|
1128
|
+
},
|
|
1129
|
+
{
|
|
1130
|
+
key: "score",
|
|
1131
|
+
label: "\u2B50 Score"
|
|
1132
|
+
},
|
|
1133
|
+
{
|
|
1134
|
+
key: "audits",
|
|
1135
|
+
label: "\u{1F6E1} Audits"
|
|
1136
|
+
}
|
|
798
1137
|
];
|
|
799
1138
|
var reportRawOverviewTableHeaders = ["Category", "Score", "Audits"];
|
|
800
|
-
var
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
"Source file",
|
|
818
|
-
"Line(s)"
|
|
1139
|
+
var issuesTableHeadings = [
|
|
1140
|
+
{
|
|
1141
|
+
key: "severity",
|
|
1142
|
+
label: "Severity"
|
|
1143
|
+
},
|
|
1144
|
+
{
|
|
1145
|
+
key: "message",
|
|
1146
|
+
label: "Message"
|
|
1147
|
+
},
|
|
1148
|
+
{
|
|
1149
|
+
key: "file",
|
|
1150
|
+
label: "Source file"
|
|
1151
|
+
},
|
|
1152
|
+
{
|
|
1153
|
+
key: "line",
|
|
1154
|
+
label: "Line(s)"
|
|
1155
|
+
}
|
|
819
1156
|
];
|
|
820
1157
|
|
|
821
1158
|
// packages/utils/src/lib/logging.ts
|
|
@@ -841,7 +1178,7 @@ function logListItem(args) {
|
|
|
841
1178
|
singletonisaacUi.rows = [];
|
|
842
1179
|
singletonUiInstance?.logger.log(content);
|
|
843
1180
|
}
|
|
844
|
-
function
|
|
1181
|
+
function link3(text) {
|
|
845
1182
|
return chalk.underline(chalk.blueBright(text));
|
|
846
1183
|
}
|
|
847
1184
|
|
|
@@ -944,122 +1281,35 @@ async function importEsmModule(options2) {
|
|
|
944
1281
|
return mod.default;
|
|
945
1282
|
}
|
|
946
1283
|
|
|
947
|
-
// packages/utils/src/lib/reports/md/details.ts
|
|
948
|
-
function details(title, content, cfg = { open: false }) {
|
|
949
|
-
return `<details${cfg.open ? " open" : ""}>
|
|
950
|
-
<summary>${title}</summary>
|
|
951
|
-
|
|
952
|
-
${content}
|
|
953
|
-
|
|
954
|
-
</details>
|
|
955
|
-
`;
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
// packages/utils/src/lib/reports/md/font-style.ts
|
|
959
|
-
var stylesMap = {
|
|
960
|
-
i: "_",
|
|
961
|
-
// italic
|
|
962
|
-
b: "**",
|
|
963
|
-
// bold
|
|
964
|
-
s: "~",
|
|
965
|
-
// strike through
|
|
966
|
-
c: "`"
|
|
967
|
-
// code
|
|
968
|
-
};
|
|
969
|
-
function style(text, styles = ["b"]) {
|
|
970
|
-
return styles.reduce((t, s) => `${stylesMap[s]}${t}${stylesMap[s]}`, text);
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
// packages/utils/src/lib/reports/md/headline.ts
|
|
974
|
-
function headline(text, hierarchy = 1) {
|
|
975
|
-
return `${"#".repeat(hierarchy)} ${text}`;
|
|
976
|
-
}
|
|
977
|
-
function h1(text) {
|
|
978
|
-
return headline(text, 1);
|
|
979
|
-
}
|
|
980
|
-
function h2(text) {
|
|
981
|
-
return headline(text, 2);
|
|
982
|
-
}
|
|
983
|
-
function h3(text) {
|
|
984
|
-
return headline(text, 3);
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
// packages/utils/src/lib/reports/md/image.ts
|
|
988
|
-
function image(src, alt) {
|
|
989
|
-
return ``;
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
// packages/utils/src/lib/reports/md/link.ts
|
|
993
|
-
function link2(href, text) {
|
|
994
|
-
return `[${text || href}](${href})`;
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
// packages/utils/src/lib/reports/md/list.ts
|
|
998
|
-
function li(text, order = "unordered") {
|
|
999
|
-
const style2 = order === "unordered" ? "-" : "- [ ]";
|
|
1000
|
-
return `${style2} ${text}`;
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
// packages/utils/src/lib/reports/md/paragraphs.ts
|
|
1004
|
-
function paragraphs(...sections) {
|
|
1005
|
-
return sections.filter(Boolean).join("\n\n");
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
// packages/utils/src/lib/reports/md/table.ts
|
|
1009
|
-
var alignString = /* @__PURE__ */ new Map([
|
|
1010
|
-
["l", ":--"],
|
|
1011
|
-
["c", ":--:"],
|
|
1012
|
-
["r", "--:"]
|
|
1013
|
-
]);
|
|
1014
|
-
function tableMd(data, align) {
|
|
1015
|
-
if (data.length === 0) {
|
|
1016
|
-
throw new Error("Data can't be empty");
|
|
1017
|
-
}
|
|
1018
|
-
const alignmentSetting = align ?? data[0]?.map(() => "c");
|
|
1019
|
-
const tableContent = data.map((arr) => `|${arr.join("|")}|`);
|
|
1020
|
-
const alignmentRow = `|${alignmentSetting?.map((s) => alignString.get(s)).join("|")}|`;
|
|
1021
|
-
return tableContent[0] + NEW_LINE + alignmentRow + NEW_LINE + tableContent.slice(1).join(NEW_LINE);
|
|
1022
|
-
}
|
|
1023
|
-
function tableHtml(data) {
|
|
1024
|
-
if (data.length === 0) {
|
|
1025
|
-
throw new Error("Data can't be empty");
|
|
1026
|
-
}
|
|
1027
|
-
const tableContent = data.map((arr, index) => {
|
|
1028
|
-
if (index === 0) {
|
|
1029
|
-
const headerRow = arr.map((s) => `<th>${s}</th>`).join("");
|
|
1030
|
-
return `<tr>${headerRow}</tr>`;
|
|
1031
|
-
}
|
|
1032
|
-
const row = arr.map((s) => `<td>${s}</td>`).join("");
|
|
1033
|
-
return `<tr>${row}</tr>`;
|
|
1034
|
-
});
|
|
1035
|
-
return `<table>${tableContent.join("")}</table>`;
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
1284
|
// packages/utils/src/lib/reports/utils.ts
|
|
1285
|
+
var { image: image2, bold: boldMd } = md;
|
|
1039
1286
|
function formatReportScore(score) {
|
|
1040
1287
|
return Math.round(score * 100).toString();
|
|
1041
1288
|
}
|
|
1042
1289
|
function formatScoreWithColor(score, options2) {
|
|
1043
|
-
const styledNumber = options2?.skipBold ? formatReportScore(score) :
|
|
1044
|
-
return `${
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1290
|
+
const styledNumber = options2?.skipBold ? formatReportScore(score) : boldMd(formatReportScore(score));
|
|
1291
|
+
return `${scoreMarker(score)} ${styledNumber}`;
|
|
1292
|
+
}
|
|
1293
|
+
var MARKERS = {
|
|
1294
|
+
circle: {
|
|
1295
|
+
red: "\u{1F534}",
|
|
1296
|
+
yellow: "\u{1F7E1}",
|
|
1297
|
+
green: "\u{1F7E2}"
|
|
1298
|
+
},
|
|
1299
|
+
square: {
|
|
1300
|
+
red: "\u{1F7E5}",
|
|
1301
|
+
yellow: "\u{1F7E8}",
|
|
1302
|
+
green: "\u{1F7E9}"
|
|
1052
1303
|
}
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
function getSquaredScoreMarker(score) {
|
|
1304
|
+
};
|
|
1305
|
+
function scoreMarker(score, markerType = "circle") {
|
|
1056
1306
|
if (score >= SCORE_COLOR_RANGE.GREEN_MIN) {
|
|
1057
|
-
return
|
|
1307
|
+
return MARKERS[markerType].green;
|
|
1058
1308
|
}
|
|
1059
1309
|
if (score >= SCORE_COLOR_RANGE.YELLOW_MIN) {
|
|
1060
|
-
return
|
|
1310
|
+
return MARKERS[markerType].yellow;
|
|
1061
1311
|
}
|
|
1062
|
-
return
|
|
1312
|
+
return MARKERS[markerType].red;
|
|
1063
1313
|
}
|
|
1064
1314
|
function getDiffMarker(diff) {
|
|
1065
1315
|
if (diff > 0) {
|
|
@@ -1075,7 +1325,7 @@ function colorByScoreDiff(text, diff) {
|
|
|
1075
1325
|
return shieldsBadge(text, color);
|
|
1076
1326
|
}
|
|
1077
1327
|
function shieldsBadge(text, color) {
|
|
1078
|
-
return
|
|
1328
|
+
return image2(
|
|
1079
1329
|
`https://img.shields.io/badge/${encodeURIComponent(text)}-${color}`,
|
|
1080
1330
|
text
|
|
1081
1331
|
);
|
|
@@ -1085,7 +1335,7 @@ function formatDiffNumber(diff) {
|
|
|
1085
1335
|
const sign = diff < 0 ? "\u2212" : "+";
|
|
1086
1336
|
return `${sign}${number}`;
|
|
1087
1337
|
}
|
|
1088
|
-
function
|
|
1338
|
+
function severityMarker(severity) {
|
|
1089
1339
|
if (severity === "error") {
|
|
1090
1340
|
return "\u{1F6A8}";
|
|
1091
1341
|
}
|
|
@@ -1258,12 +1508,12 @@ var ProcessError = class extends Error {
|
|
|
1258
1508
|
}
|
|
1259
1509
|
};
|
|
1260
1510
|
function executeProcess(cfg) {
|
|
1261
|
-
const { observer, cwd, command, args, ignoreExitCode = false } = cfg;
|
|
1511
|
+
const { observer, cwd, command: command2, args, ignoreExitCode = false } = cfg;
|
|
1262
1512
|
const { onStdout, onError, onComplete } = observer ?? {};
|
|
1263
1513
|
const date = (/* @__PURE__ */ new Date()).toISOString();
|
|
1264
1514
|
const start = performance.now();
|
|
1265
1515
|
return new Promise((resolve, reject) => {
|
|
1266
|
-
const process2 = spawn(
|
|
1516
|
+
const process2 = spawn(command2, args, { cwd, shell: true });
|
|
1267
1517
|
let stdout = "";
|
|
1268
1518
|
let stderr = "";
|
|
1269
1519
|
process2.stdout.on("data", (data) => {
|
|
@@ -1276,13 +1526,13 @@ function executeProcess(cfg) {
|
|
|
1276
1526
|
process2.on("error", (err) => {
|
|
1277
1527
|
stderr += err.toString();
|
|
1278
1528
|
});
|
|
1279
|
-
process2.on("close", (
|
|
1529
|
+
process2.on("close", (code3) => {
|
|
1280
1530
|
const timings = { date, duration: calcDuration(start) };
|
|
1281
|
-
if (
|
|
1531
|
+
if (code3 === 0 || ignoreExitCode) {
|
|
1282
1532
|
onComplete?.();
|
|
1283
|
-
resolve({ code, stdout, stderr, ...timings });
|
|
1533
|
+
resolve({ code: code3, stdout, stderr, ...timings });
|
|
1284
1534
|
} else {
|
|
1285
|
-
const errorMsg = new ProcessError({ code, stdout, stderr, ...timings });
|
|
1535
|
+
const errorMsg = new ProcessError({ code: code3, stdout, stderr, ...timings });
|
|
1286
1536
|
onError?.(errorMsg);
|
|
1287
1537
|
reject(errorMsg);
|
|
1288
1538
|
}
|
|
@@ -1298,33 +1548,9 @@ function filterItemRefsBy(items, refFilterFn) {
|
|
|
1298
1548
|
})).filter((item) => item.refs.length);
|
|
1299
1549
|
}
|
|
1300
1550
|
|
|
1301
|
-
// packages/utils/src/lib/git.ts
|
|
1551
|
+
// packages/utils/src/lib/git/git.ts
|
|
1302
1552
|
import { isAbsolute, join as join2, relative } from "node:path";
|
|
1303
1553
|
import { simpleGit } from "simple-git";
|
|
1304
|
-
|
|
1305
|
-
// packages/utils/src/lib/transform.ts
|
|
1306
|
-
function toArray(val) {
|
|
1307
|
-
return Array.isArray(val) ? val : [val];
|
|
1308
|
-
}
|
|
1309
|
-
function objectToEntries(obj) {
|
|
1310
|
-
return Object.entries(obj);
|
|
1311
|
-
}
|
|
1312
|
-
function deepClone(obj) {
|
|
1313
|
-
return obj == null || typeof obj !== "object" ? obj : structuredClone(obj);
|
|
1314
|
-
}
|
|
1315
|
-
function toUnixPath(path) {
|
|
1316
|
-
return path.replace(/\\/g, "/");
|
|
1317
|
-
}
|
|
1318
|
-
|
|
1319
|
-
// packages/utils/src/lib/git.ts
|
|
1320
|
-
async function getLatestCommit(git = simpleGit()) {
|
|
1321
|
-
const log2 = await git.log({
|
|
1322
|
-
maxCount: 1,
|
|
1323
|
-
// git log -1 --pretty=format:"%H %s %an %aI" - See: https://git-scm.com/docs/pretty-formats
|
|
1324
|
-
format: { hash: "%H", message: "%s", author: "%an", date: "%aI" }
|
|
1325
|
-
});
|
|
1326
|
-
return commitSchema.parse(log2.latest);
|
|
1327
|
-
}
|
|
1328
1554
|
function getGitRoot(git = simpleGit()) {
|
|
1329
1555
|
return git.revparse("--show-toplevel");
|
|
1330
1556
|
}
|
|
@@ -1371,11 +1597,6 @@ async function guardAgainstLocalChanges(git = simpleGit()) {
|
|
|
1371
1597
|
throw new GitStatusError(status);
|
|
1372
1598
|
}
|
|
1373
1599
|
}
|
|
1374
|
-
async function getCurrentBranchOrTag(git = simpleGit()) {
|
|
1375
|
-
return await git.branch().then((r) => r.current) || // If no current branch, try to get the tag
|
|
1376
|
-
// @TODO use simple git
|
|
1377
|
-
await git.raw(["describe", "--tags", "--exact-match"]).then((out) => out.trim());
|
|
1378
|
-
}
|
|
1379
1600
|
async function safeCheckout(branchOrHash, forceCleanStatus = false, git = simpleGit()) {
|
|
1380
1601
|
if (forceCleanStatus) {
|
|
1381
1602
|
await git.raw(["reset", "--hard"]);
|
|
@@ -1386,6 +1607,117 @@ async function safeCheckout(branchOrHash, forceCleanStatus = false, git = simple
|
|
|
1386
1607
|
await git.checkout(branchOrHash);
|
|
1387
1608
|
}
|
|
1388
1609
|
|
|
1610
|
+
// packages/utils/src/lib/git/git.commits-and-tags.ts
|
|
1611
|
+
import { simpleGit as simpleGit2 } from "simple-git";
|
|
1612
|
+
|
|
1613
|
+
// packages/utils/src/lib/semver.ts
|
|
1614
|
+
import { rcompare, valid } from "semver";
|
|
1615
|
+
function normalizeSemver(semverString) {
|
|
1616
|
+
if (semverString.startsWith("v") || semverString.startsWith("V")) {
|
|
1617
|
+
return semverString.slice(1);
|
|
1618
|
+
}
|
|
1619
|
+
if (semverString.includes("@")) {
|
|
1620
|
+
return semverString.split("@").at(-1) ?? "";
|
|
1621
|
+
}
|
|
1622
|
+
return semverString;
|
|
1623
|
+
}
|
|
1624
|
+
function isSemver(semverString = "") {
|
|
1625
|
+
return valid(normalizeSemver(semverString)) != null;
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
// packages/utils/src/lib/git/git.commits-and-tags.ts
|
|
1629
|
+
async function getLatestCommit(git = simpleGit2()) {
|
|
1630
|
+
const log2 = await git.log({
|
|
1631
|
+
maxCount: 1,
|
|
1632
|
+
// git log -1 --pretty=format:"%H %s %an %aI" - See: https://git-scm.com/docs/pretty-formats
|
|
1633
|
+
format: { hash: "%H", message: "%s", author: "%an", date: "%aI" }
|
|
1634
|
+
});
|
|
1635
|
+
return commitSchema.parse(log2.latest);
|
|
1636
|
+
}
|
|
1637
|
+
async function getCurrentBranchOrTag(git = simpleGit2()) {
|
|
1638
|
+
return await git.branch().then((r) => r.current) || // If no current branch, try to get the tag
|
|
1639
|
+
// @TODO use simple git
|
|
1640
|
+
await git.raw(["describe", "--tags", "--exact-match"]).then((out) => out.trim());
|
|
1641
|
+
}
|
|
1642
|
+
function validateFilter({ from, to }) {
|
|
1643
|
+
if (to && !from) {
|
|
1644
|
+
throw new Error(
|
|
1645
|
+
`filter needs the "from" option defined to accept the "to" option.
|
|
1646
|
+
`
|
|
1647
|
+
);
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
function filterLogs(allTags, opt) {
|
|
1651
|
+
if (!opt) {
|
|
1652
|
+
return allTags;
|
|
1653
|
+
}
|
|
1654
|
+
validateFilter(opt);
|
|
1655
|
+
const { from, to, maxCount } = opt;
|
|
1656
|
+
const finIndex = (tagName, fallback) => {
|
|
1657
|
+
const idx = allTags.indexOf(tagName ?? "");
|
|
1658
|
+
if (idx > -1) {
|
|
1659
|
+
return idx;
|
|
1660
|
+
}
|
|
1661
|
+
return fallback;
|
|
1662
|
+
};
|
|
1663
|
+
const fromIndex = finIndex(from, 0);
|
|
1664
|
+
const toIndex = finIndex(to, void 0);
|
|
1665
|
+
return allTags.slice(fromIndex, toIndex ? toIndex + 1 : toIndex).slice(0, maxCount ?? void 0);
|
|
1666
|
+
}
|
|
1667
|
+
async function getHashFromTag(tag, git = simpleGit2()) {
|
|
1668
|
+
const tagDetails = await git.show(["--no-patch", "--format=%H", tag]);
|
|
1669
|
+
const hash = tagDetails.trim();
|
|
1670
|
+
return {
|
|
1671
|
+
hash: hash.split("\n").at(-1) ?? "",
|
|
1672
|
+
message: tag
|
|
1673
|
+
};
|
|
1674
|
+
}
|
|
1675
|
+
async function getSemverTags(opt = {}, git = simpleGit2()) {
|
|
1676
|
+
validateFilter(opt);
|
|
1677
|
+
const { targetBranch, ...options2 } = opt;
|
|
1678
|
+
let currentBranch;
|
|
1679
|
+
if (targetBranch) {
|
|
1680
|
+
currentBranch = await getCurrentBranchOrTag(git);
|
|
1681
|
+
await git.checkout(targetBranch);
|
|
1682
|
+
}
|
|
1683
|
+
const tagsRaw = await git.tag([
|
|
1684
|
+
"--merged",
|
|
1685
|
+
targetBranch ?? await getCurrentBranchOrTag(git)
|
|
1686
|
+
]);
|
|
1687
|
+
const allTags = tagsRaw.split(/\n/).map((tag) => tag.trim()).filter(Boolean).filter(isSemver);
|
|
1688
|
+
const relevantTags = filterLogs(allTags, options2);
|
|
1689
|
+
const tagsWithHashes = await Promise.all(
|
|
1690
|
+
relevantTags.map((tag) => getHashFromTag(tag, git))
|
|
1691
|
+
);
|
|
1692
|
+
if (currentBranch) {
|
|
1693
|
+
await git.checkout(currentBranch);
|
|
1694
|
+
}
|
|
1695
|
+
return tagsWithHashes;
|
|
1696
|
+
}
|
|
1697
|
+
async function getHashes(options2 = {}, git = simpleGit2()) {
|
|
1698
|
+
const { targetBranch, from, to, maxCount, ...opt } = options2;
|
|
1699
|
+
validateFilter({ from, to });
|
|
1700
|
+
let currentBranch;
|
|
1701
|
+
if (targetBranch) {
|
|
1702
|
+
currentBranch = await getCurrentBranchOrTag(git);
|
|
1703
|
+
await git.checkout(targetBranch);
|
|
1704
|
+
}
|
|
1705
|
+
const logs = await git.log({
|
|
1706
|
+
...opt,
|
|
1707
|
+
format: {
|
|
1708
|
+
hash: "%H",
|
|
1709
|
+
message: "%s"
|
|
1710
|
+
},
|
|
1711
|
+
from,
|
|
1712
|
+
to,
|
|
1713
|
+
maxCount
|
|
1714
|
+
});
|
|
1715
|
+
if (targetBranch) {
|
|
1716
|
+
await git.checkout(currentBranch);
|
|
1717
|
+
}
|
|
1718
|
+
return [...logs.all];
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1389
1721
|
// packages/utils/src/lib/group-by-status.ts
|
|
1390
1722
|
function groupByStatus(results) {
|
|
1391
1723
|
return results.reduce(
|
|
@@ -1461,44 +1793,65 @@ function listAuditsFromAllPlugins(report) {
|
|
|
1461
1793
|
);
|
|
1462
1794
|
}
|
|
1463
1795
|
|
|
1464
|
-
// packages/utils/src/lib/reports/
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
`${FOOTER_PREFIX} ${link2(README_LINK, "Code PushUp")}`
|
|
1796
|
+
// packages/utils/src/lib/reports/formatting.ts
|
|
1797
|
+
var { headline: headline2, lines: lines2, link: link4, section: section2, table: table3 } = md;
|
|
1798
|
+
function tableSection(tableData, options2) {
|
|
1799
|
+
if (tableData.rows.length === 0) {
|
|
1800
|
+
return "";
|
|
1801
|
+
}
|
|
1802
|
+
const { level = 4 } = options2 ?? {};
|
|
1803
|
+
const render = (h7, l) => l === 0 ? h7 : headline2(h7, l);
|
|
1804
|
+
return lines2(
|
|
1805
|
+
tableData.title && render(tableData.title, level),
|
|
1806
|
+
table3(tableData)
|
|
1476
1807
|
);
|
|
1477
1808
|
}
|
|
1478
|
-
function
|
|
1479
|
-
|
|
1809
|
+
function metaDescription({
|
|
1810
|
+
docsUrl,
|
|
1811
|
+
description
|
|
1812
|
+
}) {
|
|
1813
|
+
if (docsUrl) {
|
|
1814
|
+
const docsLink = link4(docsUrl, "\u{1F4D6} Docs");
|
|
1815
|
+
if (!description) {
|
|
1816
|
+
return section2(docsLink);
|
|
1817
|
+
}
|
|
1818
|
+
const parsedDescription = description.toString().endsWith("```") ? `${description}${NEW_LINE + NEW_LINE}` : `${description}${SPACE}`;
|
|
1819
|
+
return section2(`${parsedDescription}${docsLink}`);
|
|
1820
|
+
}
|
|
1821
|
+
if (description && description.trim().length > 0) {
|
|
1822
|
+
return section2(description);
|
|
1823
|
+
}
|
|
1824
|
+
return "";
|
|
1480
1825
|
}
|
|
1481
|
-
|
|
1826
|
+
|
|
1827
|
+
// packages/utils/src/lib/reports/generate-md-report-categoy-section.ts
|
|
1828
|
+
var { link: link5, section: section3, h2: h22, lines: lines3, li: li2, bold: boldMd2, h3: h32, indentation: indentation2 } = md;
|
|
1829
|
+
function categoriesOverviewSection(report) {
|
|
1482
1830
|
const { categories, plugins } = report;
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1831
|
+
if (categories.length > 0 && plugins.length > 0) {
|
|
1832
|
+
const tableContent = {
|
|
1833
|
+
columns: reportOverviewTableHeaders,
|
|
1834
|
+
rows: categories.map(({ title, refs, score }) => ({
|
|
1835
|
+
// The heading "ID" is inferred from the heading text in Markdown.
|
|
1836
|
+
category: link5(`#${slugify(title)}`, title),
|
|
1837
|
+
score: `${scoreMarker(score)}${SPACE}${boldMd2(
|
|
1838
|
+
formatReportScore(score)
|
|
1839
|
+
)}`,
|
|
1840
|
+
audits: countCategoryAudits(refs, plugins).toString()
|
|
1841
|
+
}))
|
|
1842
|
+
};
|
|
1843
|
+
return tableSection(tableContent);
|
|
1844
|
+
}
|
|
1845
|
+
return "";
|
|
1492
1846
|
}
|
|
1493
|
-
function
|
|
1847
|
+
function categoriesDetailsSection(report) {
|
|
1494
1848
|
const { categories, plugins } = report;
|
|
1495
|
-
const categoryDetails = categories.
|
|
1496
|
-
const categoryTitle =
|
|
1497
|
-
const categoryScore = `${
|
|
1849
|
+
const categoryDetails = categories.flatMap((category) => {
|
|
1850
|
+
const categoryTitle = h32(category.title);
|
|
1851
|
+
const categoryScore = `${scoreMarker(
|
|
1498
1852
|
category.score
|
|
1499
|
-
)}
|
|
1500
|
-
const
|
|
1501
|
-
const categoryMDItems = category.refs.reduce((refAcc, ref) => {
|
|
1853
|
+
)}${SPACE}Score: ${boldMd2(formatReportScore(category.score))}`;
|
|
1854
|
+
const categoryMDItems = category.refs.map((ref) => {
|
|
1502
1855
|
if (ref.type === "group") {
|
|
1503
1856
|
const group = getSortableGroupByRef(ref, plugins);
|
|
1504
1857
|
const groupAudits = group.refs.map(
|
|
@@ -1508,151 +1861,240 @@ function reportToCategoriesSection(report) {
|
|
|
1508
1861
|
)
|
|
1509
1862
|
);
|
|
1510
1863
|
const pluginTitle = getPluginNameFromSlug(ref.plugin, plugins);
|
|
1511
|
-
|
|
1512
|
-
group,
|
|
1513
|
-
groupAudits,
|
|
1514
|
-
pluginTitle
|
|
1515
|
-
);
|
|
1516
|
-
return refAcc + mdGroupItem + NEW_LINE;
|
|
1864
|
+
return categoryGroupItem(group, groupAudits, pluginTitle);
|
|
1517
1865
|
} else {
|
|
1518
1866
|
const audit = getSortableAuditByRef(ref, plugins);
|
|
1519
1867
|
const pluginTitle = getPluginNameFromSlug(ref.plugin, plugins);
|
|
1520
|
-
|
|
1521
|
-
return refAcc + mdAuditItem + NEW_LINE;
|
|
1868
|
+
return categoryRef(audit, pluginTitle);
|
|
1522
1869
|
}
|
|
1523
|
-
}
|
|
1524
|
-
return
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
const auditTitle = link2(
|
|
1530
|
-
`#${slugify(audit.title)}-${slugify(pluginTitle)}`,
|
|
1531
|
-
audit.title
|
|
1532
|
-
);
|
|
1533
|
-
return li(
|
|
1534
|
-
`${getSquaredScoreMarker(
|
|
1535
|
-
audit.score
|
|
1536
|
-
)} ${auditTitle} (_${pluginTitle}_) - ${getAuditResult(audit)}`
|
|
1537
|
-
);
|
|
1538
|
-
}
|
|
1539
|
-
function groupItemToCategorySection(group, groupAudits, pluginTitle) {
|
|
1540
|
-
const groupScore = Number(formatReportScore(group.score || 0));
|
|
1541
|
-
const groupTitle = li(
|
|
1542
|
-
`${getRoundScoreMarker(groupScore)} ${group.title} (_${pluginTitle}_)`
|
|
1543
|
-
);
|
|
1544
|
-
const auditTitles = groupAudits.reduce((acc, audit) => {
|
|
1545
|
-
const auditTitle = link2(
|
|
1546
|
-
`#${slugify(audit.title)}-${slugify(pluginTitle)}`,
|
|
1547
|
-
audit.title
|
|
1870
|
+
});
|
|
1871
|
+
return section3(
|
|
1872
|
+
categoryTitle,
|
|
1873
|
+
metaDescription(category),
|
|
1874
|
+
categoryScore,
|
|
1875
|
+
...categoryMDItems
|
|
1548
1876
|
);
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
report.plugins
|
|
1563
|
-
)})`;
|
|
1564
|
-
return auditAcc + h3(auditTitle) + NEW_LINE + NEW_LINE + reportToDetailsSection(audit) + NEW_LINE + NEW_LINE + getDocsAndDescription(audit);
|
|
1565
|
-
}, "");
|
|
1566
|
-
return pluginAcc + auditsData;
|
|
1567
|
-
}, "");
|
|
1568
|
-
return h2("\u{1F6E1}\uFE0F Audits") + NEW_LINE + NEW_LINE + auditsSection;
|
|
1569
|
-
}
|
|
1570
|
-
function reportToDetailsSection(audit) {
|
|
1571
|
-
const detailsTitle = `${getSquaredScoreMarker(audit.score)} ${getAuditResult(
|
|
1572
|
-
audit,
|
|
1573
|
-
true
|
|
1574
|
-
)} (score: ${formatReportScore(audit.score)})`;
|
|
1575
|
-
if (!audit.details?.issues.length) {
|
|
1576
|
-
return detailsTitle;
|
|
1577
|
-
}
|
|
1578
|
-
const detailsTableData = [
|
|
1579
|
-
detailsTableHeaders,
|
|
1580
|
-
...audit.details.issues.map((issue) => {
|
|
1581
|
-
const severity = `${getSeverityIcon(issue.severity)} <i>${issue.severity}</i>`;
|
|
1582
|
-
const message = issue.message;
|
|
1583
|
-
if (!issue.source) {
|
|
1584
|
-
return [severity, message, "", ""];
|
|
1585
|
-
}
|
|
1586
|
-
const file = `<code>${issue.source.file}</code>`;
|
|
1587
|
-
if (!issue.source.position) {
|
|
1588
|
-
return [severity, message, file, ""];
|
|
1589
|
-
}
|
|
1590
|
-
const { startLine, endLine } = issue.source.position;
|
|
1591
|
-
const line = `${startLine || ""}${endLine && startLine !== endLine ? `-${endLine}` : ""}`;
|
|
1592
|
-
return [severity, message, file, line];
|
|
1593
|
-
})
|
|
1594
|
-
];
|
|
1595
|
-
const detailsTable = `<h4>Issues</h4>${tableHtml(detailsTableData)}`;
|
|
1596
|
-
return details(detailsTitle, detailsTable);
|
|
1597
|
-
}
|
|
1598
|
-
function reportToAboutSection(report) {
|
|
1599
|
-
const date = formatDate(/* @__PURE__ */ new Date());
|
|
1600
|
-
const { duration, version: version2, commit, plugins, categories } = report;
|
|
1601
|
-
const commitInfo = commit ? `${commit.message} (${commit.hash})` : "N/A";
|
|
1602
|
-
const reportMetaTable = [
|
|
1603
|
-
reportMetaTableHeaders,
|
|
1604
|
-
[
|
|
1605
|
-
commitInfo,
|
|
1606
|
-
style(version2 || "", ["c"]),
|
|
1607
|
-
formatDuration(duration),
|
|
1608
|
-
plugins.length.toString(),
|
|
1609
|
-
categories.length.toString(),
|
|
1610
|
-
plugins.reduce((acc, { audits }) => acc + audits.length, 0).toString()
|
|
1611
|
-
]
|
|
1612
|
-
];
|
|
1613
|
-
const pluginMetaTable = [
|
|
1614
|
-
pluginMetaTableHeaders,
|
|
1615
|
-
...plugins.map((plugin) => [
|
|
1616
|
-
plugin.title,
|
|
1617
|
-
plugin.audits.length.toString(),
|
|
1618
|
-
style(plugin.version || "", ["c"]),
|
|
1619
|
-
formatDuration(plugin.duration)
|
|
1620
|
-
])
|
|
1621
|
-
];
|
|
1622
|
-
return (
|
|
1623
|
-
// eslint-disable-next-line prefer-template
|
|
1624
|
-
h2("About") + NEW_LINE + NEW_LINE + `Report was created by [Code PushUp](${README_LINK}) on ${date}.` + NEW_LINE + NEW_LINE + tableMd(reportMetaTable, ["l", "c", "c", "c", "c", "c"]) + NEW_LINE + NEW_LINE + "The following plugins were run:" + NEW_LINE + NEW_LINE + tableMd(pluginMetaTable, ["l", "c", "c", "c"])
|
|
1877
|
+
});
|
|
1878
|
+
return lines3(h22(CATEGORIES_TITLE), ...categoryDetails);
|
|
1879
|
+
}
|
|
1880
|
+
function categoryRef({ title, score, value, displayValue }, pluginTitle) {
|
|
1881
|
+
const auditTitleAsLink = link5(
|
|
1882
|
+
`#${slugify(title)}-${slugify(pluginTitle)}`,
|
|
1883
|
+
title
|
|
1884
|
+
);
|
|
1885
|
+
const marker = scoreMarker(score, "square");
|
|
1886
|
+
return li2(
|
|
1887
|
+
`${marker}${SPACE}${auditTitleAsLink}${SPACE}(_${pluginTitle}_) - ${boldMd2(
|
|
1888
|
+
(displayValue || value).toString()
|
|
1889
|
+
)}`
|
|
1625
1890
|
);
|
|
1626
1891
|
}
|
|
1627
|
-
function
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1892
|
+
function categoryGroupItem({ score = 0, title }, groupAudits, pluginTitle) {
|
|
1893
|
+
const groupTitle = li2(
|
|
1894
|
+
`${scoreMarker(score)}${SPACE}${title}${SPACE}(_${pluginTitle}_)`
|
|
1895
|
+
);
|
|
1896
|
+
const auditTitles = groupAudits.map(
|
|
1897
|
+
({ title: auditTitle, score: auditScore, value, displayValue }) => {
|
|
1898
|
+
const auditTitleLink = link5(
|
|
1899
|
+
`#${slugify(auditTitle)}-${slugify(pluginTitle)}`,
|
|
1900
|
+
auditTitle
|
|
1901
|
+
);
|
|
1902
|
+
const marker = scoreMarker(auditScore, "square");
|
|
1903
|
+
return indentation2(
|
|
1904
|
+
li2(
|
|
1905
|
+
`${marker}${SPACE}${auditTitleLink} - ${boldMd2(
|
|
1906
|
+
String(displayValue ?? value)
|
|
1907
|
+
)}`
|
|
1908
|
+
)
|
|
1909
|
+
);
|
|
1638
1910
|
}
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1911
|
+
);
|
|
1912
|
+
return lines3(groupTitle, ...auditTitles);
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
// packages/utils/src/lib/reports/generate-md-report.ts
|
|
1916
|
+
var { h1: h12, h2: h23, h3: h33, lines: lines4, link: link6, section: section4, code: codeMd } = md;
|
|
1917
|
+
var { bold: boldHtml, details: details2 } = html;
|
|
1918
|
+
function auditDetailsAuditValue({
|
|
1919
|
+
score,
|
|
1920
|
+
value,
|
|
1921
|
+
displayValue
|
|
1922
|
+
}) {
|
|
1923
|
+
return `${scoreMarker(score, "square")} ${boldHtml(
|
|
1924
|
+
String(displayValue ?? value)
|
|
1925
|
+
)} (score: ${formatReportScore(score)})`;
|
|
1926
|
+
}
|
|
1927
|
+
function generateMdReport(report) {
|
|
1928
|
+
const printCategories = report.categories.length > 0;
|
|
1929
|
+
return lines4(
|
|
1930
|
+
h12(reportHeadlineText),
|
|
1931
|
+
printCategories ? categoriesOverviewSection(report) : "",
|
|
1932
|
+
printCategories ? categoriesDetailsSection(report) : "",
|
|
1933
|
+
auditsSection(report),
|
|
1934
|
+
aboutSection(report),
|
|
1935
|
+
`${FOOTER_PREFIX}${SPACE}${link6(README_LINK, "Code PushUp")}`
|
|
1936
|
+
);
|
|
1937
|
+
}
|
|
1938
|
+
function auditDetailsIssues(issues = []) {
|
|
1939
|
+
if (issues.length === 0) {
|
|
1940
|
+
return "";
|
|
1643
1941
|
}
|
|
1644
|
-
|
|
1942
|
+
const detailsTableData = {
|
|
1943
|
+
title: "Issues",
|
|
1944
|
+
columns: issuesTableHeadings,
|
|
1945
|
+
rows: issues.map(
|
|
1946
|
+
({ severity: severityVal, message, source: sourceVal }) => {
|
|
1947
|
+
const severity = `${severityMarker(severityVal)} <i>${severityVal}</i>`;
|
|
1948
|
+
if (!sourceVal) {
|
|
1949
|
+
return { severity, message, file: "", line: "" };
|
|
1950
|
+
}
|
|
1951
|
+
const file = `<code>${sourceVal.file}</code>`;
|
|
1952
|
+
if (!sourceVal.position) {
|
|
1953
|
+
return { severity, message, file, line: "" };
|
|
1954
|
+
}
|
|
1955
|
+
const { startLine, endLine } = sourceVal.position;
|
|
1956
|
+
const line = `${startLine || ""}${endLine && startLine !== endLine ? `-${endLine}` : ""}`;
|
|
1957
|
+
return { severity, message, file, line };
|
|
1958
|
+
}
|
|
1959
|
+
)
|
|
1960
|
+
};
|
|
1961
|
+
return tableSection(detailsTableData);
|
|
1962
|
+
}
|
|
1963
|
+
function auditDetails(audit) {
|
|
1964
|
+
const { table: table5, issues = [] } = audit.details ?? {};
|
|
1965
|
+
const detailsValue = auditDetailsAuditValue(audit);
|
|
1966
|
+
if (issues.length === 0 && table5 == null) {
|
|
1967
|
+
return section4(detailsValue);
|
|
1968
|
+
}
|
|
1969
|
+
const tableSectionContent = table5 == null ? "" : tableSection(table5);
|
|
1970
|
+
const issuesSectionContent = issues.length > 0 ? auditDetailsIssues(issues) : "";
|
|
1971
|
+
return details2(
|
|
1972
|
+
detailsValue,
|
|
1973
|
+
lines4(tableSectionContent, issuesSectionContent)
|
|
1974
|
+
);
|
|
1645
1975
|
}
|
|
1646
|
-
function
|
|
1647
|
-
|
|
1648
|
-
|
|
1976
|
+
function auditsSection({
|
|
1977
|
+
plugins
|
|
1978
|
+
}) {
|
|
1979
|
+
const content = plugins.flatMap(
|
|
1980
|
+
({ slug, audits }) => audits.flatMap((audit) => {
|
|
1981
|
+
const auditTitle = `${audit.title}${SPACE}(${getPluginNameFromSlug(
|
|
1982
|
+
slug,
|
|
1983
|
+
plugins
|
|
1984
|
+
)})`;
|
|
1985
|
+
const detailsContent = auditDetails(audit);
|
|
1986
|
+
const descriptionContent = metaDescription(audit);
|
|
1987
|
+
return [h33(auditTitle), detailsContent, descriptionContent];
|
|
1988
|
+
})
|
|
1989
|
+
);
|
|
1990
|
+
return section4(h23("\u{1F6E1}\uFE0F Audits"), ...content);
|
|
1991
|
+
}
|
|
1992
|
+
function aboutSection(report) {
|
|
1993
|
+
const { date, plugins } = report;
|
|
1994
|
+
const reportMetaTable = reportMetaData(report);
|
|
1995
|
+
const pluginMetaTable = reportPluginMeta({ plugins });
|
|
1996
|
+
return lines4(
|
|
1997
|
+
h23("About"),
|
|
1998
|
+
section4(
|
|
1999
|
+
`Report was created by [Code PushUp](${README_LINK}) on ${formatDate(
|
|
2000
|
+
new Date(date)
|
|
2001
|
+
)}.`
|
|
2002
|
+
),
|
|
2003
|
+
tableSection(pluginMetaTable),
|
|
2004
|
+
tableSection(reportMetaTable)
|
|
2005
|
+
);
|
|
2006
|
+
}
|
|
2007
|
+
function reportPluginMeta({ plugins }) {
|
|
2008
|
+
return {
|
|
2009
|
+
columns: [
|
|
2010
|
+
{
|
|
2011
|
+
key: "plugin",
|
|
2012
|
+
align: "left"
|
|
2013
|
+
},
|
|
2014
|
+
{
|
|
2015
|
+
key: "audits"
|
|
2016
|
+
},
|
|
2017
|
+
{
|
|
2018
|
+
key: "version"
|
|
2019
|
+
},
|
|
2020
|
+
{
|
|
2021
|
+
key: "duration"
|
|
2022
|
+
}
|
|
2023
|
+
],
|
|
2024
|
+
rows: plugins.map(
|
|
2025
|
+
({
|
|
2026
|
+
title: pluginTitle,
|
|
2027
|
+
audits,
|
|
2028
|
+
version: pluginVersion,
|
|
2029
|
+
duration: pluginDuration
|
|
2030
|
+
}) => ({
|
|
2031
|
+
plugin: pluginTitle,
|
|
2032
|
+
audits: audits.length.toString(),
|
|
2033
|
+
version: codeMd(pluginVersion || ""),
|
|
2034
|
+
duration: formatDuration(pluginDuration)
|
|
2035
|
+
})
|
|
2036
|
+
)
|
|
2037
|
+
};
|
|
2038
|
+
}
|
|
2039
|
+
function reportMetaData({
|
|
2040
|
+
commit,
|
|
2041
|
+
version: version2,
|
|
2042
|
+
duration,
|
|
2043
|
+
plugins,
|
|
2044
|
+
categories
|
|
2045
|
+
}) {
|
|
2046
|
+
const commitInfo = commit ? `${commit.message}${SPACE}(${commit.hash})` : "N/A";
|
|
2047
|
+
return {
|
|
2048
|
+
columns: [
|
|
2049
|
+
{
|
|
2050
|
+
key: "commit",
|
|
2051
|
+
align: "left"
|
|
2052
|
+
},
|
|
2053
|
+
{
|
|
2054
|
+
key: "version"
|
|
2055
|
+
},
|
|
2056
|
+
{
|
|
2057
|
+
key: "duration"
|
|
2058
|
+
},
|
|
2059
|
+
{
|
|
2060
|
+
key: "plugins"
|
|
2061
|
+
},
|
|
2062
|
+
{
|
|
2063
|
+
key: "categories"
|
|
2064
|
+
},
|
|
2065
|
+
{
|
|
2066
|
+
key: "audits"
|
|
2067
|
+
}
|
|
2068
|
+
],
|
|
2069
|
+
rows: [
|
|
2070
|
+
{
|
|
2071
|
+
commit: commitInfo,
|
|
2072
|
+
version: codeMd(version2 || ""),
|
|
2073
|
+
duration: formatDuration(duration),
|
|
2074
|
+
plugins: plugins.length,
|
|
2075
|
+
categories: categories.length,
|
|
2076
|
+
audits: plugins.reduce((acc, { audits }) => acc + audits.length, 0).toString()
|
|
2077
|
+
}
|
|
2078
|
+
]
|
|
2079
|
+
};
|
|
1649
2080
|
}
|
|
1650
2081
|
|
|
1651
2082
|
// packages/utils/src/lib/reports/generate-md-reports-diff.ts
|
|
2083
|
+
var {
|
|
2084
|
+
h1: h13,
|
|
2085
|
+
h2: h24,
|
|
2086
|
+
lines: lines5,
|
|
2087
|
+
link: link7,
|
|
2088
|
+
bold: boldMd3,
|
|
2089
|
+
italic: italicMd,
|
|
2090
|
+
table: table4,
|
|
2091
|
+
section: section5
|
|
2092
|
+
} = md;
|
|
2093
|
+
var { details: details3 } = html;
|
|
1652
2094
|
var MAX_ROWS = 100;
|
|
1653
2095
|
function generateMdReportsDiff(diff) {
|
|
1654
|
-
return
|
|
1655
|
-
formatDiffHeaderSection(diff),
|
|
2096
|
+
return lines5(
|
|
2097
|
+
section5(formatDiffHeaderSection(diff)),
|
|
1656
2098
|
formatDiffCategoriesSection(diff),
|
|
1657
2099
|
formatDiffGroupsSection(diff),
|
|
1658
2100
|
formatDiffAuditsSection(diff)
|
|
@@ -1660,12 +2102,12 @@ function generateMdReportsDiff(diff) {
|
|
|
1660
2102
|
}
|
|
1661
2103
|
function formatDiffHeaderSection(diff) {
|
|
1662
2104
|
const outcomeTexts = {
|
|
1663
|
-
positive: `\u{1F973} Code PushUp report has ${
|
|
1664
|
-
negative: `\u{1F61F} Code PushUp report has ${
|
|
1665
|
-
mixed: `\u{1F928} Code PushUp report has both ${
|
|
2105
|
+
positive: `\u{1F973} Code PushUp report has ${boldMd3("improved")}`,
|
|
2106
|
+
negative: `\u{1F61F} Code PushUp report has ${boldMd3("regressed")}`,
|
|
2107
|
+
mixed: `\u{1F928} Code PushUp report has both ${boldMd3(
|
|
1666
2108
|
"improvements and regressions"
|
|
1667
2109
|
)}`,
|
|
1668
|
-
unchanged: `\u{1F610} Code PushUp report is ${
|
|
2110
|
+
unchanged: `\u{1F610} Code PushUp report is ${boldMd3("unchanged")}`
|
|
1669
2111
|
};
|
|
1670
2112
|
const outcome = mergeDiffOutcomes(
|
|
1671
2113
|
changesToDiffOutcomes([
|
|
@@ -1675,8 +2117,8 @@ function formatDiffHeaderSection(diff) {
|
|
|
1675
2117
|
])
|
|
1676
2118
|
);
|
|
1677
2119
|
const styleCommits = (commits) => `compared target commit ${commits.after.hash} with source commit ${commits.before.hash}`;
|
|
1678
|
-
return
|
|
1679
|
-
|
|
2120
|
+
return lines5(
|
|
2121
|
+
h13("Code PushUp"),
|
|
1680
2122
|
diff.commits ? `${outcomeTexts[outcome]} \u2013 ${styleCommits(diff.commits)}.` : `${outcomeTexts[outcome]}.`
|
|
1681
2123
|
);
|
|
1682
2124
|
}
|
|
@@ -1687,102 +2129,104 @@ function formatDiffCategoriesSection(diff) {
|
|
|
1687
2129
|
if (categoriesCount === 0) {
|
|
1688
2130
|
return "";
|
|
1689
2131
|
}
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
formatScoreWithColor(category.scores.
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
2132
|
+
const columns = [
|
|
2133
|
+
{ key: "category", label: "\u{1F3F7}\uFE0F Category", align: "left" },
|
|
2134
|
+
{ key: "after", label: hasChanges ? "\u2B50 Current score" : "\u2B50 Score" },
|
|
2135
|
+
{ key: "before", label: "\u2B50 Previous score" },
|
|
2136
|
+
{ key: "change", label: "\u{1F504} Score change" }
|
|
2137
|
+
];
|
|
2138
|
+
return lines5(
|
|
2139
|
+
h24("\u{1F3F7}\uFE0F Categories"),
|
|
2140
|
+
categoriesCount > 0 && table4({
|
|
2141
|
+
columns: hasChanges ? columns : columns.slice(0, 2),
|
|
2142
|
+
rows: [
|
|
2143
|
+
...sortChanges(changed).map((category) => ({
|
|
2144
|
+
category: formatTitle(category),
|
|
2145
|
+
after: formatScoreWithColor(category.scores.after),
|
|
2146
|
+
before: formatScoreWithColor(category.scores.before, {
|
|
2147
|
+
skipBold: true
|
|
2148
|
+
}),
|
|
2149
|
+
change: formatScoreChange(category.scores.diff)
|
|
2150
|
+
})),
|
|
2151
|
+
...added.map((category) => ({
|
|
2152
|
+
category: formatTitle(category),
|
|
2153
|
+
after: formatScoreWithColor(category.score),
|
|
2154
|
+
before: italicMd("n/a (\\*)"),
|
|
2155
|
+
change: italicMd("n/a (\\*)")
|
|
2156
|
+
})),
|
|
2157
|
+
...unchanged.map((category) => ({
|
|
2158
|
+
category: formatTitle(category),
|
|
2159
|
+
after: formatScoreWithColor(category.score),
|
|
2160
|
+
before: formatScoreWithColor(category.score, { skipBold: true }),
|
|
2161
|
+
change: "\u2013"
|
|
2162
|
+
}))
|
|
2163
|
+
].map(
|
|
2164
|
+
(row) => hasChanges ? row : { category: row.category, after: row.after }
|
|
2165
|
+
)
|
|
2166
|
+
}),
|
|
2167
|
+
added.length > 0 && section5(italicMd("(\\*) New category."))
|
|
1722
2168
|
);
|
|
1723
2169
|
}
|
|
1724
2170
|
function formatDiffGroupsSection(diff) {
|
|
1725
2171
|
if (diff.groups.changed.length + diff.groups.unchanged.length === 0) {
|
|
1726
2172
|
return "";
|
|
1727
2173
|
}
|
|
1728
|
-
return
|
|
1729
|
-
|
|
2174
|
+
return lines5(
|
|
2175
|
+
h24("\u{1F5C3}\uFE0F Groups"),
|
|
1730
2176
|
formatGroupsOrAuditsDetails("group", diff.groups, {
|
|
1731
|
-
|
|
1732
|
-
"\u{1F50C} Plugin",
|
|
1733
|
-
"\u{1F5C3}\uFE0F Group",
|
|
1734
|
-
"\u2B50 Current score",
|
|
1735
|
-
"\u2B50 Previous score",
|
|
1736
|
-
"\u{1F504} Score change"
|
|
2177
|
+
columns: [
|
|
2178
|
+
{ key: "plugin", label: "\u{1F50C} Plugin", align: "left" },
|
|
2179
|
+
{ key: "group", label: "\u{1F5C3}\uFE0F Group", align: "left" },
|
|
2180
|
+
{ key: "after", label: "\u2B50 Current score" },
|
|
2181
|
+
{ key: "before", label: "\u2B50 Previous score" },
|
|
2182
|
+
{ key: "change", label: "\u{1F504} Score change" }
|
|
1737
2183
|
],
|
|
1738
|
-
rows: sortChanges(diff.groups.changed).map((group) =>
|
|
1739
|
-
formatTitle(group.plugin),
|
|
1740
|
-
formatTitle(group),
|
|
1741
|
-
formatScoreWithColor(group.scores.after),
|
|
1742
|
-
formatScoreWithColor(group.scores.before, { skipBold: true }),
|
|
1743
|
-
formatScoreChange(group.scores.diff)
|
|
1744
|
-
|
|
1745
|
-
align: ["l", "l", "c", "c", "c"]
|
|
2184
|
+
rows: sortChanges(diff.groups.changed).map((group) => ({
|
|
2185
|
+
plugin: formatTitle(group.plugin),
|
|
2186
|
+
group: formatTitle(group),
|
|
2187
|
+
after: formatScoreWithColor(group.scores.after),
|
|
2188
|
+
before: formatScoreWithColor(group.scores.before, { skipBold: true }),
|
|
2189
|
+
change: formatScoreChange(group.scores.diff)
|
|
2190
|
+
}))
|
|
1746
2191
|
})
|
|
1747
2192
|
);
|
|
1748
2193
|
}
|
|
1749
2194
|
function formatDiffAuditsSection(diff) {
|
|
1750
|
-
return
|
|
1751
|
-
|
|
2195
|
+
return lines5(
|
|
2196
|
+
h24("\u{1F6E1}\uFE0F Audits"),
|
|
1752
2197
|
formatGroupsOrAuditsDetails("audit", diff.audits, {
|
|
1753
|
-
|
|
1754
|
-
"\u{1F50C} Plugin",
|
|
1755
|
-
"\u{1F6E1}\uFE0F Audit",
|
|
1756
|
-
"\u{1F4CF} Current value",
|
|
1757
|
-
"\u{1F4CF} Previous value",
|
|
1758
|
-
"\u{1F504} Value change"
|
|
2198
|
+
columns: [
|
|
2199
|
+
{ key: "plugin", label: "\u{1F50C} Plugin", align: "left" },
|
|
2200
|
+
{ key: "audit", label: "\u{1F6E1}\uFE0F Audit", align: "left" },
|
|
2201
|
+
{ key: "after", label: "\u{1F4CF} Current value" },
|
|
2202
|
+
{ key: "before", label: "\u{1F4CF} Previous value" },
|
|
2203
|
+
{ key: "change", label: "\u{1F504} Value change" }
|
|
1759
2204
|
],
|
|
1760
|
-
rows: sortChanges(diff.audits.changed).map((audit) =>
|
|
1761
|
-
formatTitle(audit.plugin),
|
|
1762
|
-
formatTitle(audit),
|
|
1763
|
-
`${
|
|
2205
|
+
rows: sortChanges(diff.audits.changed).map((audit) => ({
|
|
2206
|
+
plugin: formatTitle(audit.plugin),
|
|
2207
|
+
audit: formatTitle(audit),
|
|
2208
|
+
after: `${scoreMarker(audit.scores.after, "square")} ${boldMd3(
|
|
1764
2209
|
audit.displayValues.after || audit.values.after.toString()
|
|
1765
2210
|
)}`,
|
|
1766
|
-
`${
|
|
1767
|
-
formatValueChange(audit)
|
|
1768
|
-
|
|
1769
|
-
align: ["l", "l", "c", "c", "c"]
|
|
2211
|
+
before: `${scoreMarker(audit.scores.before, "square")} ${audit.displayValues.before || audit.values.before.toString()}`,
|
|
2212
|
+
change: formatValueChange(audit)
|
|
2213
|
+
}))
|
|
1770
2214
|
})
|
|
1771
2215
|
);
|
|
1772
2216
|
}
|
|
1773
|
-
function formatGroupsOrAuditsDetails(token, { changed, unchanged },
|
|
1774
|
-
return changed.length === 0 ? summarizeUnchanged(token, { changed, unchanged }) :
|
|
2217
|
+
function formatGroupsOrAuditsDetails(token, { changed, unchanged }, tableData) {
|
|
2218
|
+
return changed.length === 0 ? summarizeUnchanged(token, { changed, unchanged }) : details3(
|
|
1775
2219
|
summarizeDiffOutcomes(changesToDiffOutcomes(changed), token),
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
2220
|
+
lines5(
|
|
2221
|
+
table4({
|
|
2222
|
+
...tableData,
|
|
2223
|
+
rows: tableData.rows.slice(0, MAX_ROWS)
|
|
2224
|
+
// use never to avoid typing problem
|
|
2225
|
+
}),
|
|
2226
|
+
changed.length > MAX_ROWS && italicMd(
|
|
1782
2227
|
`Only the ${MAX_ROWS} most affected ${pluralize(
|
|
1783
2228
|
token
|
|
1784
|
-
)} are listed above for brevity
|
|
1785
|
-
["i"]
|
|
2229
|
+
)} are listed above for brevity.`
|
|
1786
2230
|
),
|
|
1787
2231
|
unchanged.length > 0 && summarizeUnchanged(token, { changed, unchanged })
|
|
1788
2232
|
)
|
|
@@ -1803,11 +2247,13 @@ function formatValueChange({
|
|
|
1803
2247
|
return colorByScoreDiff(`${marker} ${text}`, scores.diff);
|
|
1804
2248
|
}
|
|
1805
2249
|
function summarizeUnchanged(token, { changed, unchanged }) {
|
|
1806
|
-
return
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
2250
|
+
return section5(
|
|
2251
|
+
[
|
|
2252
|
+
changed.length > 0 ? pluralizeToken(`other ${token}`, unchanged.length) : `All of ${pluralizeToken(token, unchanged.length)}`,
|
|
2253
|
+
unchanged.length === 1 ? "is" : "are",
|
|
2254
|
+
"unchanged."
|
|
2255
|
+
].join(" ")
|
|
2256
|
+
);
|
|
1811
2257
|
}
|
|
1812
2258
|
function summarizeDiffOutcomes(outcomes, token) {
|
|
1813
2259
|
return objectToEntries(countDiffOutcomes(outcomes)).filter(
|
|
@@ -1832,7 +2278,7 @@ function formatTitle({
|
|
|
1832
2278
|
docsUrl
|
|
1833
2279
|
}) {
|
|
1834
2280
|
if (docsUrl) {
|
|
1835
|
-
return
|
|
2281
|
+
return link7(docsUrl, title);
|
|
1836
2282
|
}
|
|
1837
2283
|
return title;
|
|
1838
2284
|
}
|
|
@@ -1883,7 +2329,7 @@ function log(msg = "") {
|
|
|
1883
2329
|
}
|
|
1884
2330
|
function logStdoutSummary(report) {
|
|
1885
2331
|
const printCategories = report.categories.length > 0;
|
|
1886
|
-
log(
|
|
2332
|
+
log(reportToHeaderSection(report));
|
|
1887
2333
|
log();
|
|
1888
2334
|
logPlugins(report);
|
|
1889
2335
|
if (printCategories) {
|
|
@@ -1892,7 +2338,7 @@ function logStdoutSummary(report) {
|
|
|
1892
2338
|
log(`${FOOTER_PREFIX} ${CODE_PUSHUP_DOMAIN}`);
|
|
1893
2339
|
log();
|
|
1894
2340
|
}
|
|
1895
|
-
function
|
|
2341
|
+
function reportToHeaderSection(report) {
|
|
1896
2342
|
const { packageName, version: version2 } = report;
|
|
1897
2343
|
return `${chalk4.bold(reportHeadlineText)} - ${packageName}@${version2}`;
|
|
1898
2344
|
}
|
|
@@ -1932,16 +2378,16 @@ function logCategories({ categories, plugins }) {
|
|
|
1932
2378
|
applyScoreColor({ score }),
|
|
1933
2379
|
countCategoryAudits(refs, plugins)
|
|
1934
2380
|
]);
|
|
1935
|
-
const
|
|
1936
|
-
|
|
1937
|
-
|
|
2381
|
+
const table5 = ui().table();
|
|
2382
|
+
table5.columnWidths([TERMINAL_WIDTH - 9 - 10 - 4, 9, 10]);
|
|
2383
|
+
table5.head(
|
|
1938
2384
|
reportRawOverviewTableHeaders.map((heading, idx) => ({
|
|
1939
2385
|
content: chalk4.cyan(heading),
|
|
1940
2386
|
hAlign: hAlign(idx)
|
|
1941
2387
|
}))
|
|
1942
2388
|
);
|
|
1943
2389
|
rows.forEach(
|
|
1944
|
-
(row) =>
|
|
2390
|
+
(row) => table5.row(
|
|
1945
2391
|
row.map((content, idx) => ({
|
|
1946
2392
|
content: content.toString(),
|
|
1947
2393
|
hAlign: hAlign(idx)
|
|
@@ -1950,19 +2396,19 @@ function logCategories({ categories, plugins }) {
|
|
|
1950
2396
|
);
|
|
1951
2397
|
log(chalk4.magentaBright.bold("Categories"));
|
|
1952
2398
|
log();
|
|
1953
|
-
|
|
2399
|
+
table5.render();
|
|
1954
2400
|
log();
|
|
1955
2401
|
}
|
|
1956
2402
|
function applyScoreColor({ score, text }) {
|
|
1957
2403
|
const formattedScore = text ?? formatReportScore(score);
|
|
1958
|
-
const
|
|
2404
|
+
const style = text ? chalk4 : chalk4.bold;
|
|
1959
2405
|
if (score >= SCORE_COLOR_RANGE.GREEN_MIN) {
|
|
1960
|
-
return
|
|
2406
|
+
return style.green(formattedScore);
|
|
1961
2407
|
}
|
|
1962
2408
|
if (score >= SCORE_COLOR_RANGE.YELLOW_MIN) {
|
|
1963
|
-
return
|
|
2409
|
+
return style.yellow(formattedScore);
|
|
1964
2410
|
}
|
|
1965
|
-
return
|
|
2411
|
+
return style.red(formattedScore);
|
|
1966
2412
|
}
|
|
1967
2413
|
|
|
1968
2414
|
// packages/utils/src/lib/reports/scoring.ts
|
|
@@ -2124,12 +2570,22 @@ var verboseUtils = (verbose = false) => ({
|
|
|
2124
2570
|
|
|
2125
2571
|
// packages/core/package.json
|
|
2126
2572
|
var name = "@code-pushup/core";
|
|
2127
|
-
var version = "0.
|
|
2573
|
+
var version = "0.42.0";
|
|
2128
2574
|
|
|
2129
2575
|
// packages/core/src/lib/implementation/execute-plugin.ts
|
|
2130
2576
|
import chalk5 from "chalk";
|
|
2131
2577
|
|
|
2132
2578
|
// packages/core/src/lib/normalize.ts
|
|
2579
|
+
function normalizeIssue(issue, gitRoot) {
|
|
2580
|
+
const { source, ...issueWithoutSource } = issue;
|
|
2581
|
+
return source == null ? issue : {
|
|
2582
|
+
...issueWithoutSource,
|
|
2583
|
+
source: {
|
|
2584
|
+
...source,
|
|
2585
|
+
file: formatGitPath(source.file, gitRoot)
|
|
2586
|
+
}
|
|
2587
|
+
};
|
|
2588
|
+
}
|
|
2133
2589
|
async function normalizeAuditOutputs(audits) {
|
|
2134
2590
|
const gitRoot = await getGitRoot();
|
|
2135
2591
|
return audits.map((audit) => {
|
|
@@ -2141,13 +2597,7 @@ async function normalizeAuditOutputs(audits) {
|
|
|
2141
2597
|
details: {
|
|
2142
2598
|
...audit.details,
|
|
2143
2599
|
issues: audit.details.issues.map(
|
|
2144
|
-
(issue) => issue
|
|
2145
|
-
...issue,
|
|
2146
|
-
source: {
|
|
2147
|
-
...issue.source,
|
|
2148
|
-
file: formatGitPath(issue.source.file, gitRoot)
|
|
2149
|
-
}
|
|
2150
|
-
}
|
|
2600
|
+
(issue) => normalizeIssue(issue, gitRoot)
|
|
2151
2601
|
)
|
|
2152
2602
|
}
|
|
2153
2603
|
};
|
|
@@ -2157,9 +2607,9 @@ async function normalizeAuditOutputs(audits) {
|
|
|
2157
2607
|
// packages/core/src/lib/implementation/runner.ts
|
|
2158
2608
|
import { join as join3 } from "node:path";
|
|
2159
2609
|
async function executeRunnerConfig(cfg, onProgress) {
|
|
2160
|
-
const { args, command, outputFile, outputTransform } = cfg;
|
|
2610
|
+
const { args, command: command2, outputFile, outputTransform } = cfg;
|
|
2161
2611
|
const { duration, date } = await executeProcess({
|
|
2162
|
-
command,
|
|
2612
|
+
command: command2,
|
|
2163
2613
|
args,
|
|
2164
2614
|
observer: { onStdout: onProgress }
|
|
2165
2615
|
});
|
|
@@ -2185,7 +2635,11 @@ async function executeRunnerFunction(runner, onProgress) {
|
|
|
2185
2635
|
// packages/core/src/lib/implementation/execute-plugin.ts
|
|
2186
2636
|
var PluginOutputMissingAuditError = class extends Error {
|
|
2187
2637
|
constructor(auditSlug) {
|
|
2188
|
-
super(
|
|
2638
|
+
super(
|
|
2639
|
+
`Audit metadata not present in plugin config. Missing slug: ${chalk5.bold(
|
|
2640
|
+
auditSlug
|
|
2641
|
+
)}`
|
|
2642
|
+
);
|
|
2189
2643
|
}
|
|
2190
2644
|
};
|
|
2191
2645
|
async function executePlugin(pluginConfig, onProgress) {
|
|
@@ -2199,7 +2653,11 @@ async function executePlugin(pluginConfig, onProgress) {
|
|
|
2199
2653
|
} = pluginConfig;
|
|
2200
2654
|
const runnerResult = typeof runner === "object" ? await executeRunnerConfig(runner, onProgress) : await executeRunnerFunction(runner, onProgress);
|
|
2201
2655
|
const { audits: unvalidatedAuditOutputs, ...executionMeta } = runnerResult;
|
|
2202
|
-
const
|
|
2656
|
+
const result = auditOutputsSchema.safeParse(unvalidatedAuditOutputs);
|
|
2657
|
+
if (!result.success) {
|
|
2658
|
+
throw new Error(`Audit output is invalid: ${result.error.message}`);
|
|
2659
|
+
}
|
|
2660
|
+
const auditOutputs = result.data;
|
|
2203
2661
|
auditOutputsCorrelateWithPluginOutput(auditOutputs, pluginConfigAudits);
|
|
2204
2662
|
const normalizedAuditOutputs = await normalizeAuditOutputs(auditOutputs);
|
|
2205
2663
|
const auditReports = normalizedAuditOutputs.map(
|
|
@@ -2219,32 +2677,48 @@ async function executePlugin(pluginConfig, onProgress) {
|
|
|
2219
2677
|
...groups2 && { groups: groups2 }
|
|
2220
2678
|
};
|
|
2221
2679
|
}
|
|
2680
|
+
var wrapProgress = async (pluginCfg, steps, progressBar) => {
|
|
2681
|
+
progressBar?.updateTitle(`Executing ${chalk5.bold(pluginCfg.title)}`);
|
|
2682
|
+
try {
|
|
2683
|
+
const pluginReport = await executePlugin(pluginCfg);
|
|
2684
|
+
progressBar?.incrementInSteps(steps);
|
|
2685
|
+
return pluginReport;
|
|
2686
|
+
} catch (error) {
|
|
2687
|
+
progressBar?.incrementInSteps(steps);
|
|
2688
|
+
throw new Error(
|
|
2689
|
+
error instanceof Error ? `- Plugin ${chalk5.bold(pluginCfg.title)} (${chalk5.bold(
|
|
2690
|
+
pluginCfg.slug
|
|
2691
|
+
)}) produced the following error:
|
|
2692
|
+
- ${error.message}` : String(error)
|
|
2693
|
+
);
|
|
2694
|
+
}
|
|
2695
|
+
};
|
|
2222
2696
|
async function executePlugins(plugins, options2) {
|
|
2223
2697
|
const { progress = false } = options2 ?? {};
|
|
2224
2698
|
const progressBar = progress ? getProgressBar("Run plugins") : null;
|
|
2225
|
-
const pluginsResult = await plugins.reduce(
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
progressBar?.incrementInSteps(plugins.length);
|
|
2233
|
-
return [
|
|
2234
|
-
...await acc,
|
|
2235
|
-
Promise.reject(error instanceof Error ? error.message : String(error))
|
|
2236
|
-
];
|
|
2237
|
-
}
|
|
2238
|
-
}, Promise.resolve([]));
|
|
2699
|
+
const pluginsResult = await plugins.reduce(
|
|
2700
|
+
async (acc, pluginCfg) => [
|
|
2701
|
+
...await acc,
|
|
2702
|
+
wrapProgress(pluginCfg, plugins.length, progressBar)
|
|
2703
|
+
],
|
|
2704
|
+
Promise.resolve([])
|
|
2705
|
+
);
|
|
2239
2706
|
progressBar?.endProgress("Done running plugins");
|
|
2240
2707
|
const errorsTransform = ({ reason }) => String(reason);
|
|
2241
2708
|
const results = await Promise.allSettled(pluginsResult);
|
|
2242
2709
|
logMultipleResults(results, "Plugins", void 0, errorsTransform);
|
|
2243
2710
|
const { fulfilled, rejected } = groupByStatus(results);
|
|
2244
2711
|
if (rejected.length > 0) {
|
|
2245
|
-
const errorMessages = rejected.map(({ reason }) => String(reason)).join("
|
|
2712
|
+
const errorMessages = rejected.map(({ reason }) => String(reason)).join("\n");
|
|
2246
2713
|
throw new Error(
|
|
2247
|
-
`
|
|
2714
|
+
`Executing ${pluralizeToken(
|
|
2715
|
+
"plugin",
|
|
2716
|
+
rejected.length
|
|
2717
|
+
)} failed.
|
|
2718
|
+
|
|
2719
|
+
${errorMessages}
|
|
2720
|
+
|
|
2721
|
+
`
|
|
2248
2722
|
);
|
|
2249
2723
|
}
|
|
2250
2724
|
return fulfilled.map((result) => result.value);
|
|
@@ -2541,9 +3015,6 @@ function reportsDiffToFileContent(reportsDiff, format) {
|
|
|
2541
3015
|
}
|
|
2542
3016
|
}
|
|
2543
3017
|
|
|
2544
|
-
// packages/core/src/lib/history.ts
|
|
2545
|
-
import { simpleGit as simpleGit2 } from "simple-git";
|
|
2546
|
-
|
|
2547
3018
|
// packages/core/src/lib/upload.ts
|
|
2548
3019
|
import {
|
|
2549
3020
|
uploadToPortal
|
|
@@ -2589,17 +3060,33 @@ function groupToGQL(group) {
|
|
|
2589
3060
|
};
|
|
2590
3061
|
}
|
|
2591
3062
|
function auditToGQL(audit) {
|
|
3063
|
+
const {
|
|
3064
|
+
slug,
|
|
3065
|
+
title,
|
|
3066
|
+
description,
|
|
3067
|
+
docsUrl,
|
|
3068
|
+
score,
|
|
3069
|
+
value,
|
|
3070
|
+
displayValue: formattedValue,
|
|
3071
|
+
details: details4
|
|
3072
|
+
} = audit;
|
|
3073
|
+
const {
|
|
3074
|
+
issues
|
|
3075
|
+
/*, table */
|
|
3076
|
+
} = details4 ?? {};
|
|
2592
3077
|
return {
|
|
2593
|
-
slug
|
|
2594
|
-
title
|
|
2595
|
-
description
|
|
2596
|
-
docsUrl
|
|
2597
|
-
score
|
|
2598
|
-
value
|
|
2599
|
-
formattedValue
|
|
2600
|
-
...
|
|
3078
|
+
slug,
|
|
3079
|
+
title,
|
|
3080
|
+
description,
|
|
3081
|
+
docsUrl,
|
|
3082
|
+
score,
|
|
3083
|
+
value,
|
|
3084
|
+
formattedValue,
|
|
3085
|
+
...details4 && {
|
|
2601
3086
|
details: {
|
|
2602
|
-
issues:
|
|
3087
|
+
...issues && { issues: issues.map(issueToGQL) }
|
|
3088
|
+
// @TODO add when https://github.com/code-pushup/cli/issues/530 is implemented
|
|
3089
|
+
// ...(table ? {table} : {}),
|
|
2603
3090
|
}
|
|
2604
3091
|
}
|
|
2605
3092
|
};
|
|
@@ -2706,24 +3193,6 @@ async function history(config, commits) {
|
|
|
2706
3193
|
await safeCheckout(initialBranch, forceCleanStatus);
|
|
2707
3194
|
return reports;
|
|
2708
3195
|
}
|
|
2709
|
-
async function getHashes(options2, git = simpleGit2()) {
|
|
2710
|
-
const { from, to } = options2;
|
|
2711
|
-
if (to && !from) {
|
|
2712
|
-
throw new Error(
|
|
2713
|
-
`git log command needs the "from" option defined to accept the "to" option.
|
|
2714
|
-
`
|
|
2715
|
-
);
|
|
2716
|
-
}
|
|
2717
|
-
const logs = await git.log({
|
|
2718
|
-
...options2,
|
|
2719
|
-
from,
|
|
2720
|
-
to
|
|
2721
|
-
});
|
|
2722
|
-
return prepareHashes(logs);
|
|
2723
|
-
}
|
|
2724
|
-
function prepareHashes(logs) {
|
|
2725
|
-
return logs.all.map(({ hash }) => hash).reverse();
|
|
2726
|
-
}
|
|
2727
3196
|
|
|
2728
3197
|
// packages/core/src/lib/implementation/read-rc-file.ts
|
|
2729
3198
|
import { join as join6 } from "node:path";
|
|
@@ -2774,7 +3243,7 @@ import chalk6 from "chalk";
|
|
|
2774
3243
|
function renderConfigureCategoriesHint() {
|
|
2775
3244
|
ui().logger.info(
|
|
2776
3245
|
chalk6.gray(
|
|
2777
|
-
`\u{1F4A1} Configure categories to see the scores in an overview table. See: ${
|
|
3246
|
+
`\u{1F4A1} Configure categories to see the scores in an overview table. See: ${link3(
|
|
2778
3247
|
"https://github.com/code-pushup/cli/blob/main/packages/cli/README.md"
|
|
2779
3248
|
)}`
|
|
2780
3249
|
)
|
|
@@ -2782,7 +3251,7 @@ function renderConfigureCategoriesHint() {
|
|
|
2782
3251
|
}
|
|
2783
3252
|
function uploadSuccessfulLog(url) {
|
|
2784
3253
|
ui().logger.success("Upload successful!");
|
|
2785
|
-
ui().logger.success(
|
|
3254
|
+
ui().logger.success(link3(url));
|
|
2786
3255
|
}
|
|
2787
3256
|
function collectSuccessfulLog() {
|
|
2788
3257
|
ui().logger.success("Collecting report successful!");
|
|
@@ -2793,15 +3262,15 @@ function renderIntegratePortalHint() {
|
|
|
2793
3262
|
"npx code-pushup upload"
|
|
2794
3263
|
)}`
|
|
2795
3264
|
).add(
|
|
2796
|
-
` ${
|
|
3265
|
+
` ${link3(
|
|
2797
3266
|
"https://github.com/code-pushup/cli/tree/main/packages/cli#upload-command"
|
|
2798
3267
|
)}`
|
|
2799
3268
|
).add(
|
|
2800
|
-
`${chalk6.gray("\u276F")} ${chalk6.gray("Portal Integration")} - ${
|
|
3269
|
+
`${chalk6.gray("\u276F")} ${chalk6.gray("Portal Integration")} - ${link3(
|
|
2801
3270
|
"https://github.com/code-pushup/cli/blob/main/packages/cli/README.md#portal-integration"
|
|
2802
3271
|
)}`
|
|
2803
3272
|
).add(
|
|
2804
|
-
`${chalk6.gray("\u276F")} ${chalk6.gray("Upload Command")} - ${
|
|
3273
|
+
`${chalk6.gray("\u276F")} ${chalk6.gray("Upload Command")} - ${link3(
|
|
2805
3274
|
"https://github.com/code-pushup/cli/blob/main/packages/cli/README.md#portal-integration"
|
|
2806
3275
|
)}`
|
|
2807
3276
|
).render();
|
|
@@ -2809,13 +3278,13 @@ function renderIntegratePortalHint() {
|
|
|
2809
3278
|
|
|
2810
3279
|
// packages/cli/src/lib/autorun/autorun-command.ts
|
|
2811
3280
|
function yargsAutorunCommandObject() {
|
|
2812
|
-
const
|
|
3281
|
+
const command2 = "autorun";
|
|
2813
3282
|
return {
|
|
2814
|
-
command,
|
|
3283
|
+
command: command2,
|
|
2815
3284
|
describe: "Shortcut for running collect followed by upload",
|
|
2816
3285
|
handler: async (args) => {
|
|
2817
3286
|
ui().logger.log(chalk7.bold(CLI_NAME));
|
|
2818
|
-
ui().logger.info(chalk7.gray(`Run ${
|
|
3287
|
+
ui().logger.info(chalk7.gray(`Run ${command2}...`));
|
|
2819
3288
|
const options2 = args;
|
|
2820
3289
|
const optionsWithFormat = {
|
|
2821
3290
|
...options2,
|
|
@@ -2845,14 +3314,14 @@ function yargsAutorunCommandObject() {
|
|
|
2845
3314
|
// packages/cli/src/lib/collect/collect-command.ts
|
|
2846
3315
|
import chalk8 from "chalk";
|
|
2847
3316
|
function yargsCollectCommandObject() {
|
|
2848
|
-
const
|
|
3317
|
+
const command2 = "collect";
|
|
2849
3318
|
return {
|
|
2850
|
-
command,
|
|
3319
|
+
command: command2,
|
|
2851
3320
|
describe: "Run Plugins and collect results",
|
|
2852
3321
|
handler: async (args) => {
|
|
2853
3322
|
const options2 = args;
|
|
2854
3323
|
ui().logger.log(chalk8.bold(CLI_NAME));
|
|
2855
|
-
ui().logger.info(chalk8.gray(`Run ${
|
|
3324
|
+
ui().logger.info(chalk8.gray(`Run ${command2}...`));
|
|
2856
3325
|
await collectAndPersistReports(options2);
|
|
2857
3326
|
collectSuccessfulLog();
|
|
2858
3327
|
if (options2.categories.length === 0) {
|
|
@@ -2871,7 +3340,7 @@ function renderUploadAutorunHint() {
|
|
|
2871
3340
|
"Run upload to upload the created report to the server"
|
|
2872
3341
|
)}`
|
|
2873
3342
|
).add(
|
|
2874
|
-
` ${
|
|
3343
|
+
` ${link3(
|
|
2875
3344
|
"https://github.com/code-pushup/cli/tree/main/packages/cli#upload-command"
|
|
2876
3345
|
)}`
|
|
2877
3346
|
).add(
|
|
@@ -2879,7 +3348,7 @@ function renderUploadAutorunHint() {
|
|
|
2879
3348
|
"Run collect & upload"
|
|
2880
3349
|
)}`
|
|
2881
3350
|
).add(
|
|
2882
|
-
` ${
|
|
3351
|
+
` ${link3(
|
|
2883
3352
|
"https://github.com/code-pushup/cli/tree/main/packages/cli#autorun-command"
|
|
2884
3353
|
)}`
|
|
2885
3354
|
).render();
|
|
@@ -2906,14 +3375,14 @@ function yargsCompareOptionsDefinition() {
|
|
|
2906
3375
|
|
|
2907
3376
|
// packages/cli/src/lib/compare/compare-command.ts
|
|
2908
3377
|
function yargsCompareCommandObject() {
|
|
2909
|
-
const
|
|
3378
|
+
const command2 = "compare";
|
|
2910
3379
|
return {
|
|
2911
|
-
command,
|
|
3380
|
+
command: command2,
|
|
2912
3381
|
describe: "Compare 2 report files and create a diff file",
|
|
2913
3382
|
builder: yargsCompareOptionsDefinition(),
|
|
2914
3383
|
handler: async (args) => {
|
|
2915
3384
|
ui().logger.log(chalk9.bold(CLI_NAME));
|
|
2916
|
-
ui().logger.info(chalk9.gray(`Run ${
|
|
3385
|
+
ui().logger.info(chalk9.gray(`Run ${command2}...`));
|
|
2917
3386
|
const options2 = args;
|
|
2918
3387
|
const { before, after, persist } = options2;
|
|
2919
3388
|
const outputPaths = await compareReportFiles({ before, after }, persist);
|
|
@@ -2970,8 +3439,12 @@ function yargsHistoryOptionsDefinition() {
|
|
|
2970
3439
|
return {
|
|
2971
3440
|
targetBranch: {
|
|
2972
3441
|
describe: "Branch to crawl history",
|
|
2973
|
-
type: "string"
|
|
2974
|
-
|
|
3442
|
+
type: "string"
|
|
3443
|
+
},
|
|
3444
|
+
onlySemverTags: {
|
|
3445
|
+
describe: "Skip commits not tagged with a semantic version",
|
|
3446
|
+
type: "boolean",
|
|
3447
|
+
default: false
|
|
2975
3448
|
},
|
|
2976
3449
|
forceCleanStatus: {
|
|
2977
3450
|
describe: "If we reset the status to a clean git history forcefully or not.",
|
|
@@ -3003,9 +3476,68 @@ function yargsHistoryOptionsDefinition() {
|
|
|
3003
3476
|
};
|
|
3004
3477
|
}
|
|
3005
3478
|
|
|
3479
|
+
// packages/cli/src/lib/history/utils.ts
|
|
3480
|
+
async function normalizeHashOptions(processArgs) {
|
|
3481
|
+
const {
|
|
3482
|
+
onlySemverTags,
|
|
3483
|
+
// overwritten
|
|
3484
|
+
maxCount,
|
|
3485
|
+
...opt
|
|
3486
|
+
} = processArgs;
|
|
3487
|
+
let { from, to, ...processOptions } = opt;
|
|
3488
|
+
if (!onlySemverTags) {
|
|
3489
|
+
if (from && isSemver(from)) {
|
|
3490
|
+
const { hash } = await getHashFromTag(from);
|
|
3491
|
+
from = hash;
|
|
3492
|
+
}
|
|
3493
|
+
if (to && isSemver(to)) {
|
|
3494
|
+
const { hash } = await getHashFromTag(to);
|
|
3495
|
+
to = hash;
|
|
3496
|
+
}
|
|
3497
|
+
}
|
|
3498
|
+
return {
|
|
3499
|
+
...processOptions,
|
|
3500
|
+
onlySemverTags,
|
|
3501
|
+
maxCount: maxCount && maxCount > 0 ? maxCount : void 0,
|
|
3502
|
+
from,
|
|
3503
|
+
to
|
|
3504
|
+
};
|
|
3505
|
+
}
|
|
3506
|
+
|
|
3006
3507
|
// packages/cli/src/lib/history/history-command.ts
|
|
3508
|
+
var command = "history";
|
|
3509
|
+
async function handler(args) {
|
|
3510
|
+
ui().logger.info(chalk10.bold(CLI_NAME));
|
|
3511
|
+
ui().logger.info(chalk10.gray(`Run ${command}`));
|
|
3512
|
+
const currentBranch = await getCurrentBranchOrTag();
|
|
3513
|
+
const { targetBranch: rawTargetBranch, ...opt } = args;
|
|
3514
|
+
const {
|
|
3515
|
+
targetBranch,
|
|
3516
|
+
from,
|
|
3517
|
+
to,
|
|
3518
|
+
maxCount,
|
|
3519
|
+
onlySemverTags,
|
|
3520
|
+
...historyOptions
|
|
3521
|
+
} = await normalizeHashOptions({
|
|
3522
|
+
...opt,
|
|
3523
|
+
targetBranch: rawTargetBranch ?? currentBranch
|
|
3524
|
+
});
|
|
3525
|
+
const filterOptions = { targetBranch, from, to, maxCount };
|
|
3526
|
+
const results = onlySemverTags ? await getSemverTags(filterOptions) : await getHashes(filterOptions);
|
|
3527
|
+
try {
|
|
3528
|
+
const reports = await history(
|
|
3529
|
+
{
|
|
3530
|
+
targetBranch,
|
|
3531
|
+
...historyOptions
|
|
3532
|
+
},
|
|
3533
|
+
results.map(({ hash }) => hash)
|
|
3534
|
+
);
|
|
3535
|
+
ui().logger.log(`Reports: ${reports.length}`);
|
|
3536
|
+
} finally {
|
|
3537
|
+
await safeCheckout(currentBranch);
|
|
3538
|
+
}
|
|
3539
|
+
}
|
|
3007
3540
|
function yargsHistoryCommandObject() {
|
|
3008
|
-
const command = "history";
|
|
3009
3541
|
return {
|
|
3010
3542
|
command,
|
|
3011
3543
|
describe: "Collect reports for commit history",
|
|
@@ -3020,41 +3552,15 @@ function yargsHistoryCommandObject() {
|
|
|
3020
3552
|
);
|
|
3021
3553
|
return yargs2;
|
|
3022
3554
|
},
|
|
3023
|
-
handler
|
|
3024
|
-
ui().logger.info(chalk10.bold(CLI_NAME));
|
|
3025
|
-
ui().logger.info(chalk10.gray(`Run ${command}`));
|
|
3026
|
-
const currentBranch = await getCurrentBranchOrTag();
|
|
3027
|
-
const {
|
|
3028
|
-
targetBranch = currentBranch,
|
|
3029
|
-
forceCleanStatus,
|
|
3030
|
-
maxCount,
|
|
3031
|
-
from,
|
|
3032
|
-
to,
|
|
3033
|
-
...restOptions
|
|
3034
|
-
} = args;
|
|
3035
|
-
const commits = await getHashes({ maxCount, from, to });
|
|
3036
|
-
try {
|
|
3037
|
-
const reports = await history(
|
|
3038
|
-
{
|
|
3039
|
-
...restOptions,
|
|
3040
|
-
targetBranch,
|
|
3041
|
-
forceCleanStatus
|
|
3042
|
-
},
|
|
3043
|
-
commits
|
|
3044
|
-
);
|
|
3045
|
-
ui().logger.log(`Reports: ${reports.length}`);
|
|
3046
|
-
} finally {
|
|
3047
|
-
await safeCheckout(currentBranch);
|
|
3048
|
-
}
|
|
3049
|
-
}
|
|
3555
|
+
handler
|
|
3050
3556
|
};
|
|
3051
3557
|
}
|
|
3052
3558
|
|
|
3053
3559
|
// packages/cli/src/lib/print-config/print-config-command.ts
|
|
3054
3560
|
function yargsConfigCommandObject() {
|
|
3055
|
-
const
|
|
3561
|
+
const command2 = "print-config";
|
|
3056
3562
|
return {
|
|
3057
|
-
command,
|
|
3563
|
+
command: command2,
|
|
3058
3564
|
describe: "Print config",
|
|
3059
3565
|
handler: (yargsArgs) => {
|
|
3060
3566
|
const { _, $0, ...args } = yargsArgs;
|
|
@@ -3067,13 +3573,13 @@ function yargsConfigCommandObject() {
|
|
|
3067
3573
|
// packages/cli/src/lib/upload/upload-command.ts
|
|
3068
3574
|
import chalk11 from "chalk";
|
|
3069
3575
|
function yargsUploadCommandObject() {
|
|
3070
|
-
const
|
|
3576
|
+
const command2 = "upload";
|
|
3071
3577
|
return {
|
|
3072
|
-
command,
|
|
3578
|
+
command: command2,
|
|
3073
3579
|
describe: "Upload report results to the portal",
|
|
3074
3580
|
handler: async (args) => {
|
|
3075
3581
|
ui().logger.log(chalk11.bold(CLI_NAME));
|
|
3076
|
-
ui().logger.info(chalk11.gray(`Run ${
|
|
3582
|
+
ui().logger.info(chalk11.gray(`Run ${command2}...`));
|
|
3077
3583
|
const options2 = args;
|
|
3078
3584
|
if (options2.upload == null) {
|
|
3079
3585
|
renderIntegratePortalHint();
|